【学习笔记】尚硅谷-AJAX
Ajax简介
Asynchronous JavaScript And XML:在不网页无刷新跳转的情况下,向服务器(后端)发送HTTP请求并得到HTTP响应
Ajax就是一个异步无刷新请求,无需更新整个页面就异步加载一些数据,交互性更强。
Ajax优缺点
- 无需刷新页面即可与服务器端进行通信。
- 允许根据用户事件来更新部分页面内容。
- 无浏览历史,不能回退。
- 存在跨域问题(同源):如
a.com
向b.com
发送AJAX请求默认是不可行的。- SEO(Search Engine Optimization)不友好。
如何使用Ajax?
- 原生
- JQuery
- fetch函数
- axios工具包
XML简介
可扩展标记语言(eXtensible Markup Language)。
与HTML的区别?
XML 被设计用来传输和存储数据,其焦点是数据的内容;HTML 被设计用来显示数据,其焦点是数据的外观。
(1)可扩展性方面:HTML不允许用户自行定义他们自己的标识或属性,而在XML中,用户能够根据需要自行定义新的标识及属性名,以便更好地从语义上修饰数据。
(2)结构性方面:HTML不支持深层的结构描述,XML的文件结构嵌套可以复杂到任意程度,能表示面向对象的等级层次。
(3)可校验性方面:HTML没有提供规范文件以支持应用软件对HTML文件进行结构校验,而XML文件可以包括一个语法描述,使应用程序可以对此文件进行结构校验。
AJAX的数据传输格式现在已经逐渐被JSON取代。
HTTP相关问题
MDN 文档
- 应用从浏览器端向服务器发送HTTP请求(请求报文)
- 后台服务器接收到请求后, 调度服务器应用处理请求, 向浏览器端返回HTTP响应(响应报文)
- 浏览器端接收到响应, 解析显示响应体/调用监视回调
- HTTP请求报文
请求行 method URL 协议版本
如:POST /s?ie=utf-8 HTTP/1.1
---
请求头
Host: baidu.com
Cookie: BAIDUID=AD3B0FA706E; BIDUPSID=AD3B0FA706;
Content-Type: application/x-www-form-urlencoded # 或者application/json
User-Agent: chrome ...
...
---
请求体
username=tom&pwd=123 # or {"username": "tom", "pwd": 123}
- HTTP响应报文
响应状态行 status statusText
如:200 OK
---
响应头
Content-Type: text/html?charset=utf-8
Content-Length: 2048
Content-encoding: gzip
...
响应体
# HTML代码/json文本/js/css/图片
- POST请求体参数格式
Content-Type: application/x-www-form-urlencoded;charset=utf-8
# 用于键值对参数,参数的键值使用“=”连接,参数之间使用“&”连接
如:name=小小&age=11
---
Content-Type: application/json;charset=utf-8
# 用于json字符串参数
如:{"name": "小小","age":11}
---
Content-Type: multipart/form-data
# 用于文件上传请求
常见的响应状态码
200 OK
请求成功。一般用于GET 与POST 请求
201 Created
已创建。成功请求并创建了新的资源
401 Unauthorized
未授权/请求要求用户的身份认证
404 Not Found
服务器无法根据客户端的请求找到资源
500 Internal Server Error
服务器内部错误,无法完成请求
不同类型的请求及其作用
GET
: 从服务器端读取数据(查)POST
: 向服务器端添加新数据 (增)PUT
: 更新服务器端已经数据 (改)DELETE
: 删除服务器端数据 (删)
API 的分类
REST API: restful (Representational State Transfer (资源)表现层状态转化)
(1) 发送请求进行CRUD 哪个操作由请求方式来决定
(2) 同一个请求路径可以进行多个操作
(3) 请求方式会用到GET/POST/PUT/DELETE非REST API: restless
(1) 请求方式不决定请求的CRUD 操作
(2) 一个请求路径只对应一个操作
(3) 一般只有GET/POST
http请求与ajax请求的区别
- ajax请求是一种特别的 http请求
- 对服务器端来说,,没有任何区别, 区别在浏览器端
- 浏览器端发请求:只有
XHR
或fetch
发出的才是ajax 请求,其它所有的都是非ajax 请求 - 浏览器端接收到响应
(1) 一般请求:浏览器一般会直接显示响应体数据, 也就是我们常说的刷新/跳转页面
(2) ajax请求:浏览器不会对界面进行任何更新操作, 只是调用监视的回调函数并传入响应相关数据
原生AJAX:使用 XHR
XHR(XMLHttpRequest)用于与服务器交互数据,是AJAX功能实现所依赖的对象,JQuery中的AJAX就是对XHR的封装。
XMLHttpRequest 对象提供了对 HTTP 协议的完全的访问,包括做出 POST 和 HEAD 请求以及普通的 GET 请求的能力。XMLHttpRequest 可以同步或异步地返回 Web 服务器的响应,并且能够以文本或者一个 DOM 文档的形式返回内容。
XHR接口强制要求每个请求都具备严格的HTTP语义–应用提供数据和URL,浏览器格式化请求并管理每个连接的完整生命周期,所以XHR仅仅允许应用自定义一些HTTP首部,但更多的首部是不能自己设定的,如:
Accept-Charset, Accept-Encoding, Access-Control-* Host, Upgrade, Connection, Referer, Origin Cookie, Sec-, Proxy-, 及其他首部
准备工作
个人觉得 node.js(执行.js文件的JavaScript代码)和 npm 有些类似 python 解释器和 pip 包管理工具的关系。
安装
node.js
Node.js发布于2009年5月,是一个基于Chrome V8引擎的JavaScript【事件驱动脚本语言】运行环境,使用了一个事件驱动、非阻塞式I/O模型, 让JavaScript 运行在服务端的开发平台。
简单的说 Node.js 就是运行在服务端的 JavaScript
Node可以在不新增额外线程的情况下,依然可以对任务进行并发处理 —— Node.js是单线程的。它通过事件循环(event loop)来实现并发操作,对此,我们应该要充分利用这一点 —— 尽可能的避免阻塞操作,取而代之,多使用非阻塞操作。
安装地址:http://nodejs.cn/
第一个程序
Node.js 应用组成部分:
- 引入 required 模块:使用 require 指令来载入 Node.js 模块。
- 创建服务器:服务器可以监听客户端的请求,类似于 Apache 、Nginx 等 HTTP 服务器。
- 接收请求与响应请求 :服务器很容易创建,客户端可以使用浏览器或终端发送 HTTP 请求,服务器接收请求后返回响应数据。
在项目的根目录下创建一个叫
server.js
的文件,写入以下代码:var http = require('http');http.createServer(function (request, response) {// 发送 HTTP 头部// HTTP 状态值: 200 : OK// 内容类型: text/plainresponse.writeHead(200, {'Content-Type': 'text/plain'});// 发送响应数据 "Hello World"response.send('Hello World\n'); }).listen(8888);// 终端打印如下信息 console.log('Server running at http://127.0.0.1:8888/');
以上代码我们完成了一个可以工作的 HTTP 服务器。使用
node
命令执行以上的代码:node server.js ## Server running at http://127.0.0.1:8888/
NPM
NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种:
- 允许用户从NPM服务器下载别人编写的第三方包到本地使用。
- 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。
- 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。
由于新版的nodejs已经集成了npm,所以之前npm也一并安装好了。同样可以通过输入 “npm -v” 来测试是否成功安装。
安装express(web框架模块)
Express中文网:https://www.expressjs.com.cn/
nodeJS相关和npm使用参考:https://www.runoob.com/nodejs/nodejs-npm.html
- 初始化环境(在项目根目录下)
npm init --yes
- 安装express模块(项目路径下)
npm install express --save npm install express -g --save # 全局
- 编写js代码
// 1. 引入express const express = require('express');// 2. 创建应用对象 const app = express();// 3. 创建路由规则 // request 是对请求报文的封装 // response 是对响应报文的封装 app.get('/', (request, response) => {// 设置响应response.send("Hello Express"); });// 4. 监听端口,启动服务 app.listen(8000, () => {console.log("server is running on http://127.0.0.1:8000/");})
- 运行程序
安装nodemon自动重启工具
文件内容有修改自动重新启动服务:https://www.npmjs.com/package/nodemon
安装
npm install -g nodemon
启动服务
ndoemon server.js
注意点:
- 使用
XMLHttpRequest
(XHR)对象可以与服务器交互, 也就是发送ajax 请求 - 前端可以获取到数据,而无需让整个的页面刷新。(使得Web 页面可以只更新页面的局部,而不影响用户的操作)
XHR文档:https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest。
AJAX 的所有操作都是通过该对象进行的
核心对象使用步骤
创建XMLHttpRequest 对象
var xhr = new XMLHttpRequest();
设置请求信息(请求方法和url)
// 请求方式 xhr.open(method, url); //可以设置请求头,一般不设置 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');// 自定义请求头 xhr.setRequestHeader('name', 'moonjay'); // 自定义请求头需要在server.js加入 response.setHeader('Access-Control-Allow-Headers', '*');
发送请求
xhr.send(body) //get请求不传 body 参数,只有post请求使用
接收响应(事件绑定,处理服务端返回的结果)
//xhr.responseXML 接收 xml格式 的响应数据 //xhr.responseText 接收 文本格式 的响应数据 xhr.onreadystatechange = function(){// readyState 是 xhr对象中的属性, 表示状态 0 1 2 3 4if(xhr.readyState == 4 && xhr.status == 200){var text = xhr.responseText;console.log(text);} }
AJAX 请求状态
xhr.readyState
可以用来查看请求当前的状态
文档链接:https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/readyState
- 0: 表示XMLHttpRequest 实例已经生成,但是open()方法还没有被调用
- 1: 表示send()方法还没有被调用,仍然可以使用setRequestHeader(),设定HTTP请求的头信息
- 2: 表示send()方法已经执行,并且头信息和状态码已经收到
- 3: 表示正在接收服务器传来的body 部分的数据
- 4: 表示服务器数据已经完全接收,或者本次接收已经失败了
示例
GET 请求(点击返回响应信息)
文件结构(浏览器端–html文件;服务器端–js文件)
server.js
:// 1. 引入express const express = require('express');// 2. 创建应用对象 const app = express();// 3. 创建路由规则 app.get('/server', (request, response) => {// 设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 设置响应体response.send("Hello Ajax"); });// 4. 监听服务 app.listen(8000, () => {console.log("server is running on http://127.0.0.1:8000/");})
01Get.html
:<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Ajax GET 请求</title><style>#result {width: 200px;height: 100px;border: solid 1px #90b;}</style> </head> <body><button>点击发送请求</button><div id="result"></div><script>//获取button元素const btn = document.getElementsByTagName('button')[0];const result = document.getElementById('result');//绑定事件btn.onclick = function(){// 1. 创建对象const xhr = new XMLHttpRequest();// 2. 初始化 设置请求方法和urlxhr.open('GET', 'http://127.0.0.1:8000/server')// 3. 发送, GET不发送body POST发送xhr.send();// 4. 事件绑定 处理服务端返回的结果xhr.onreadystatechange = function(){// readyState 是 xhr 对象中的属性, 表示状态 0 1 2 3 4//判断 (服务端返回了所有的结果)if(xhr.readyState === 4){//判断响应状态码 200 404 403 401 500if(xhr.status >= 200 && xhr.status < 300){// 处理结果 行 头 空行 体// 响应行console.log('状态码', xhr.status); // 状态码console.log('状态字符串', xhr.statusText); // 状态字符串console.log('所有响应头', xhr.getAllResponseHeaders()); // 所有响应头console.log('响应体', xhr.response); // 响应体//设置 result 的文本result.innerHTML=xhr.response;}else{}}} }</script> </body> </html>
GET 请求设置请求参数
xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');
可以在Headers中看到Query String Parameters多出三个参数
POST请求(鼠标放到div中,发post请求,将响应体放在div中呈现)
server.js
添加POSTapp.post('/server', (request, response) => {// 设置响应头, 设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 设置响应体response.send("Hello Ajax POST"); });
01Post.html
:<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Ajax POST 请求</title><style>#result {width: 200px;height: 100px;border: solid 1px #903;}</style> </head> <body><div id="result"></div><script>// 获取元素对象const result = document.getElementById('result');// 绑定事件result.addEventListener("mouseover", function(){// 1. 创建对象const xhr = new XMLHttpRequest();// 2. 初始化 设置类型(请求方式)与urlxhr.open('POST', 'http://127.0.0.1:8000/server');// 3. 发送 设置请求参数(请求体),可以说任意类型的xhr.send('a=100&b=200&c=300');// 4. 事件绑定xhr.onreadystatechange = function(){// 判断if(xhr.readyState === 4){if(xhr.status >=200 && xhr.status < 300){// 处理服务端返回的结果result.innerHTML = xhr.response;}}}});</script> </body> </html>
JSON数据请求
server.js
中设置响应头允许自定义请求头post改成all
// app.all() -- 可以get、post
app.all('/json-server', (request, response) => {// 设置响应头, 设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 设置响应头, 设置允许自定义头信息response.setHeader('Access-Control-Allow-Headers', '*');// 响应一个数据const data = {name: 'moonjay'};// 对 对象 进行 字符串 转换let str = JSON.stringify(data)// 设置响应体response.send(str);
});
01JSON.html
:(按下键盘任意按键触发)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>JSON</title><style>#result {width: 200px;height: 100px;border: solid 1px #89b;}</style>
</head>
<body><div id="result"></div><script>const result = document.getElementById('result');// 绑定键盘按下事件window.onkeydown = function(){// 发送请求const xhr = new XMLHttpRequest();// *2*.(自动转换) 设置响应体数据的类型(自动转换)xhr.responseType = 'json';// 初始化xhr.open('GET', 'http://127.0.0.1:8000/json-server');// 发送xhr.send();// 事件绑定xhr.onreadystatechange = function(){if(xhr.readyState === 4){if(xhr.status >= 200 && xhr.status < 300){console.log(xhr.response);// 1. 手动对数据转化 (字符串再转换成json)// let data = JSON.parse(xhr.response); //转换成json// result.innerHTML = data.name;// 2. 自动转换result.innerHTML = xhr.response.name; //已经自动变成json}}}}</script>
</body>
</html>
请求超时与网络异常
// 超时设置 (2秒)
xhr.timeout = 2000;
// 超时回调
xhr.ontimeout = function(){alert('网络超时,请稍后重试')
}
// 网络异常回调 在chrome’检查‘的Network选项卡可以设置网络环境--设为offline
xhr.onerror = function(){alert('网络异常,请稍后重试')
}
// 手动取消请求
xhr.abort()
在server.js
中设置:
app.get('/delay', (request, response) =>{response.setHeader('Access-Control-Allow-Origin', '*');setTimeout(() => {response.send('延时响应');}, 3000)
});
重复请求问题
用户可能重复向服务器发送相同请求,造成服务器端响应压力,如何解决?
创建一个只有一个按钮的html网页,html代码略,下为script脚本:
const btn = document.querySelector('button')
let x = null;
// 标识变量 是否正在发送AJAX请求
let isSending = false;
btn.onclick = function(){// 判断标识变量,如果正在发送,则取消该请求创建一个新的请求if(isSending) x.abort();x = new XMLHttpRequest();// 修改标识变量的值isSending = true;x.open("GET", "http://127.0.0.1:8000/delay");x.send();x.onreadystatechange = function(){if(x.readyState === 4){//修改标识变量isSending = false;}}
}
IE 缓存问题
问题:在一些浏览器中(IE),由于缓存机制的存在,ajax 只会发送的第一次请求,剩余多次请求不会在发送给浏览器而是直接加载缓存中的数据。
解决方式:浏览器的缓存是根据url 地址来记录的,所以我们只需要修改url 地址即可避免缓存问题。
xhr.open("get","/testAJAX?t="+Date.now());
API总结
XMLHttpRequest()
:创建 XHR 对象的构造函数status
:响应状态码值,如 200、404statusText
:响应状态文本,如 ’ok‘、‘not found’readyState
:标识请求状态的只读属性 0-1-2-3-4onreadystatechange
:绑定 readyState 改变的监听responseType
:指定响应数据类型,如果是 ‘json’,得到响应后自动解析响应response
:响应体数据,类型取决于 responseType 的指定timeout
:指定请求超时时间,默认为 0 代表没有限制ontimeout
:绑定超时的监听onerror
:绑定请求网络错误的监听open()
:初始化一个请求,参数为:(method, url[, async])
send(data)
:发送请求abort()
:中断请求 (发出到返回之间)getResponseHeader(name)
:获取指定名称的响应头值getAllResponseHeaders()
:获取所有响应头组成的字符串setRequestHeader(name, value)
:设置请求头
JQuery中的AJAX
get 请求
$.get(url, [data], [callback], [type])
post 请求
$.post(url, [data], [callback], [type])
- url:请求的URL 地址
- data:请求携带的参数
- callback:载入成功时回调函数
- type:设置返回内容格式,xml, html, script, json, text, _default
通用方法
$.ajax({// urlurl: 'http://127.0.0.1:8000/jquery-server',// 参数data: {a:100, b:200},// 请求类型type: 'GET',// 响应体结果dataType: 'json',// 成功的回调success: function(data){console.log(data);},// 超时时间timeout: 2000,// 失败的回调error: function(){console.log('出错la~');},// 头信息headers: {c: 300,d: 400}
})
示例
JQuery_AJAX.html
:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>JQuery发送Ajax请求</title><!--crossorigin="anonymous"是跨域匿名请求的意思,向css或js文件发送请求时不会携带当前站点的cookies--><link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="stylesheet"><script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.min.js"></script></head><body><div class="container"><h2 class="page-header">JQuery发送Ajax请求</h2><button class="btn btn-primary">GET</button><button class="btn btn-danger">POST</button><button class="btn btn-info">通用型方法Ajax</button></div></body><script>$('button').eq(0).click(function(){$.get('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){console.log(data)}, 'json'); //响应体类型为json})$('button').eq(1).click(function(){$.post('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){console.log(data)}); //响应体类型为字符串})$('button').eq(2).click(function(){$.ajax({// urlurl: 'http://127.0.0.1:8000/jquery-server',// 参数data: {a:100, b:200},// 请求类型type: 'GET',// 响应体结果--可选,默认为字符串dataType: 'json',// 成功的回调success: function(data){console.log(data);},// 超时时间timeout: 2000,// 失败的回调error: function(){console.log('出错la~');},// 头信息headers: {c: 300,d: 400}});})</script>
</html>
server.js
加入以下代码:
// JQuery_AJAX.html文件用 all--可以响应get和post
app.all('/jquery-server', (request, response) => {// 设置响应头response.setHeader('Access-Control-Allow-Origin', '*');// 设置响应头, 设置允许自定义头信息,// 第3个按钮有头信息参数,不设置会出错response.setHeader('Access-Control-Allow-Headers', '*');// response.send("hello JQuery AJAX");// 响应体类型为jsonconst data = {name: "moonjay"};response.send(JSON.stringify(data))
});
axios发送AJAX请求
axios的Github链接:https://github.com/axios/axios
是一个基于promise的网络请求库,作用于node.js和浏览器中,它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生node.js http模块, 而在客户端 (浏览端) 则使用XMLHttpRequest。
axios本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范。
主要特点:
- 从浏览器创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御XSRF
-
【学习笔记】尚硅谷-AJAX相关推荐
- MySQL学习笔记——尚硅谷李玉婷经典版MySQL基础笔记(一)
MySQL学习笔记--尚硅谷李玉婷经典版MySQL基础笔记(一) MySQL学习笔记目录 MySQL学习笔记--尚硅谷李玉婷经典版MySQL基础笔记(一) 一.基础知识 1.MySQL的语法规范 2. ...
- maven学习笔记——尚硅谷
文章目录 maven学习笔记--尚硅谷 第一章 Maven概述 第一节 为什么要学习Maven 1.Maven 作为依赖管理工具 1.1 jar 包的规模 1.2 jar 包的来源 1.3 jar 包 ...
- Rabbitmq学习笔记(尚硅谷2021)
Rabbitmq学习笔记 (尚硅谷) 1.MQ 的概念 1.1 什么是 MQ? 1.2 为什么要用 MQ? 削峰 解耦 异步 1.3 MQ 的分类 ActiveMQ Kafka RocketMQ Ra ...
- 【HBase学习笔记-尚硅谷-Java API shell命令 谷粒微博案例】
HBase学习笔记 HBase 一.HBase简介 1.HBase介绍 2.HBase的逻辑结构和物理结构 3.数据模型 4.基本架构 二.快速入门 1.配置HBase 2.命令 三.API 1.获取 ...
- Java学习笔记 | 尚硅谷项目三详解
该笔记基于B站视频:尚硅谷Java入门视频教程 目录 1,目标 2,需求说明 2.1,功能实现 2.1,菜单显示 2.2,添加功能 2.3,删除功能 2.3,查看团队成员 3,软件设计结构 4,具体实 ...
- javaWeb学习笔记(尚硅谷旧版+新版)
HTML基础 目录 HTML基础 HTML书写规范 HTML标签 简介 特殊字符 a标签 列表标签 img标签 table标签 跨行跨列表格 iframe标签 表单标签 关于GET和POST请求 ...
- [Java]Maven学习笔记(尚硅谷2022)
文章目录
- Springboot学习笔记 | 尚硅谷雷神
一.springboot入门 1.导入依赖 导入springboot版本仲裁中心 <parent><groupId>org.springframework.boot</g ...
- Elasticsearch7学习笔记(尚硅谷)
文章目录 一.ElasticSearch概述 1.ElasticSearch是什么 2.全文搜索引擎 3.ElasticSearch 和 Solr 3.1 概述 3.2 比较总结 二.Elastics ...
- [Vue]Vue3学习笔记(尚硅谷)
文章目录
最新文章
- linu逻辑分区动态调整大小
- C++知识:__stdcall、__cdcel和__fastcall三者的区别
- 编译原理三大经典书籍(龙书 虎书 鲸书)
- Linux 的启动流程--转
- 老师吴恩达,身家又增20亿!
- Android之提示Caused by: java.lang.UnsupportedOperationException: Binary XML file line #67: You must sup
- 【转载保存】lucene优秀文章整理
- php原生类,反序列化之PHP原生类的利用
- centos安装mysql5.7.26_Centos安装mysql5.7.26
- CDH秘籍(两):cloudera Manager存储监控数据
- [转]百度地图的一些应用方法
- 【Pygame闯关游戏】手残勿入,最新虐心游戏《见缝插针》——不得不玩的一款游戏。
- 服务器配置Token验证失败
- 百度竞价ocpc投放是一门玄学吗
- OPPO加入连接标准联盟董事会;BOSE为领克09汽车打造Centerpoint环绕声音响系统 | 全球TMT...
- 国产手机干翻苹果?原来是靠百元机和猛降价实现的
- java 中心度_任务调度中心 (优化版)【原】
- 假设知道服务器IP,如何查询它绑定的域名?
- 大数据技术之电商推荐系统(6) | 基于LFM的离线推荐模块
- 项目开发经验谈之:设计失败的挫败感
热门文章
- QQ是成年人的“不老神仙水”
- 【教程】PDF控件Spire.PDF 教程:在C#中加密和解密PDF文件
- 计算机win7截长屏,电脑截长图【应对法子】
- 2019PHP最新简历
- ccccccccccccccccccccc
- Java实现密码加密
- Springboot+Vue实现物业管理系统
- 安装福昕高级PDF编辑器提示安装错误解决办法
- Dataset之图片数据增强:设计自动生成汽车车牌图片算法(cv2+PIL)根据指定七个字符自动生成逼真车牌图片数据集(带各种噪声效果)
- U8服务器怎么修改会计制度,用友GRP-U8乡镇财政精细化管理新会计制度操作手册..doc...
- MySQL学习笔记——尚硅谷李玉婷经典版MySQL基础笔记(一)