Ajax介绍

  1. 1. 关于Ajax的介绍
    1. 1.1. Ajax特点:
    2. 1.2. HTTP协议
      1. 1.2.1. 请求报文
      2. 1.2.2. 响应报文
      3. 1.2.3. 状态码
      4. 1.2.4. 常见响应状态码
    3. 1.3. Ajax请求
      1. 1.3.1. 基本操作
      2. 1.3.2. 设置请求参数
      3. 1.3.3. 发送POST请求
      4. 1.3.4. 设置请求头信息
      5. 1.3.5. 设置响应体数据的类型
      6. 1.3.6. 请求超时处理
      7. 1.3.7. 网络异常处理
      8. 1.3.8. 取消请求
    4. 1.4. jQuery中的Ajax
      1. 1.4.1. 引入jQuery
      2. 1.4.2. 发送请求
      3. 1.4.3. 通用方法发送Ajax请求
      4. 1.4.4. 请求配置
    5. 1.5. axios中的Ajax
      1. 1.5.1. 引入axios
      2. 1.5.2. 发送请求
      3. 1.5.3. 通用方法发送Ajax请求
      4. 1.5.4. 请求配置
      5. 1.5.5. 响应结构和处理
    6. 1.6. 跨域
      1. 1.6.1. 同源策略
      2. 1.6.2. JSONP方案
      3. 1.6.3. CORS方案

关于Ajax的介绍

AJAX: 全称Asynchronous JavaScript And XML,即异步JS和XML。

Ajax特点:

优点

  • 可以无需刷新页面,与服务器进行通信。
  • 允许依据用户事件来更新部分页面内容。

缺点

  • 没有浏览历史,不能回退
  • 存在跨域问题(同源)
  • SEO不友好(搜索引擎优化,对爬虫不友好)

HTTP协议

HTTP(hypertext transport protocol)协议超文本传输协议),协议详细规定了浏览器和万维网服务器之间互相通信的规则。(一种约定,规则)

请求报文

1
2
3
4
5
请求行      POST /url HTTP/1.1
请求头 Host: ycfsh.top
Content-type: application/x-www-form-urlencoded
空行
请求体 key=123456

响应报文

1
2
3
4
5
响应行      HTTP/1.1 200 OK
响应头 Content-type: text/html;charset=utf-8
Content-length: 2048
空行
响应体 <html></html>

状态码

状态码分类 说明
1xx 响应中——临时状态码,表示请求已经接受,告诉客户端应该继续请求或者如果它已经完成则忽略它
2xx 成功——表示请求已经被成功接收,处理已完成
3xx 重定向——重定向到其它地方:它让客户端再发起一个请求以完成整个处理。
4xx 客户端错误——处理发生错误,责任在客户端,如:客户端的请求一个不存在的资源,客户端未被授权,禁止访问等
5xx 服务器端错误——处理发生错误,责任在服务端,如:服务端抛出异常,路由出错,HTTP版本不支持等

常见响应状态码

图像

状态码

状态码 响应状态字符 说明
200 OK 客户端请求成功,即处理成功,这是我们最想看到的状态码
302 Found 指示所请求的资源已移动到由Location响应头给定的 URL,浏览器会自动重新访问到这个页面
304 Not Modified 告诉客户端,你请求的资源至上次取得后,服务端并未更改,你直接用你本地缓存吧。隐式重定向
400 Bad Request 客户端请求有语法错误,不能被服务器所理解
403 Forbidden 服务器收到请求,但是拒绝提供服务,比如:没有权限访问相关资源
404 Not Found 请求资源不存在,一般是URL输入有误,或者网站资源被删除了
428 Precondition Required 服务器要求有条件的请求,告诉客户端要想访问该资源,必须携带特定的请求头
429 Too Many Requests 太多请求,可以限制客户端请求某个资源的数量,配合 Retry-After(多长时间后可以请求)响应头一起使用
431 Request Header Fields Too Large 请求头太大,服务器不愿意处理请求,因为它的头部字段太大。请求可以在减少请求头域的大小后重新提交。
405 Method Not Allowed 请求方式有误,比如应该用GET请求方式的资源,用了POST
500 Internal Server Error 服务器发生不可预期的错误。服务器出异常了,赶紧看日志去吧
503 Service Unavailable 服务器尚未准备好处理请求,服务器刚刚启动,还未初始化好
511 Network Authentication Required 客户端需要进行身份验证才能获得网络访问权限

Ajax请求

基本操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化 设置请求方法和url
xhr.open("GET","http://127.0.0.1:8080/login");
// 3.发送
xhr.send();
// 4.事件绑定 处理服务端返回的结果
// readystate : 0 1 2 3 4
xhr.onreadystatechange = function(){
// 判断服务端已经放回了全部数据
if(xhr.readyState === 4){
// 判断响应状态码
if(xhr.status >= 200 && xhr.status < 300){
// 处理结果(响应行 响应头 空行 响应体)
console.log(xhr.status); // 状态码
console.log(xhr.statusText); // 状态字符串
console.log(xhr.getAllResponseHeaders()); // 所有的响应头
console.log(xhr.response); // 响应体

}
}
}
readystate值 状态 描述
0 UNSENT 代理被创建,但尚未调用 open() 方法。
1 OPENED open() 方法已经被调用。
2 HEADERS_RECEIVED send() 方法已经被调用,并且头部和状态已经可获得。
3 LOADING 下载中;responseText 属性已经包含部分数据。
4 DONE 下载操作已完成。

设置请求参数

在地址后加请求参数

1
xhr.open("GET","http://127.0.0.1:8080/login?user=123456&passwd=123456");

发送POST请求

修改请求方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化 设置请求方法和url
xhr.open("POST","http://127.0.0.1:8080/login");
// 3.发送
xhr.send();
// 4.事件绑定 处理服务端返回的结果
// readystate : 0 1 2 3 4
xhr.onreadystatechange = function(){
// 判断服务端已经放回了全部数据
if(xhr.readyState === 4){
// 判断响应状态码
if(xhr.status >= 200 && xhr.status < 300){
// 处理结果(响应行 响应头 空行 响应体)
console.log(xhr.status); // 状态码
console.log(xhr.statusText); // 状态字符串
console.log(xhr.getAllResponseHeaders()); // 所有的响应头
console.log(xhr.response); // 响应体
}
}
}

设置POST请求参数 (请求体设置)

1
xhr.send("user=123456&passwd=123456");

设置请求头信息

1
2
3
4
// 发送
xhr.send();
// 设置请求头
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencode');

设置响应体数据的类型

1
2
// 设置响应体数据的类型
xhr.responseText = 'json'

请求超时处理

1
2
3
4
5
6
// 超时 2s 设置
xhr.timeout = 2000;
// 超时回调
xhr.ontimeout = function(){
// 超时回调处理
}

网络异常处理

1
2
3
4
// 网络异常回调
xhr.onerror = function(){
// 网络异常处理
}

取消请求

1
2
// 取消请求
xhr.abort();

jQuery中的Ajax

引入jQuery

下载jQuery并引入。

1
2
3
<head>
<script src="jquery-1.10.2.min.js"></script>
</head>

通过百度 CDN引入

1
2
3
4
<head>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js">
</script>
</head>

发送请求

  • GET

1
2
3
4
5
6
// 地址-请求参数-响应回调-响应体数据类型
$.get('http://127.0.0.1:8080/login',
{user: '123456',passwd: '123456'},
function(data){
// data为响应体
},'json')
  • POST

1
2
3
4
5
6
// 地址-请求参数-响应回调-响应体数据类型
$.post('http://127.0.0.1:8080/login',
{user: '123456',passwd: '123456'},
function(data){
// data为响应体
},'json')

通用方法发送Ajax请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$.ajax({
url: "http://127.0.0.1:8080/login",
data: {user: '123456',passwd: '123456'},
type: 'GET',
dataType: 'json',
headers: {
'Content-type': 'application/x-www-form-urlencoded'
},
success: function(data){
// 成功回调
},
timeout: 2000,
error: function(){
// 失败回调
}
})

请求配置

键值对描述
名称 值/描述
async 布尔值,表示请求是否异步处理。默认是 true。
beforeSend(xhr) 发送请求前运行的函数。
cache 布尔值,表示浏览器是否缓存被请求页面。默认是 true。
complete(xhr,status) 请求完成时运行的函数(在请求成功或失败之后均调用,即在 success 和 error 函数之后)。
contents 字符串/正则表达式对的对象,用于确定 jQuery 在给定其内容类型的情况下如何解析响应。
contentType 发送数据到服务器时所使用的内容类型。默认是:“application/x-www-form-urlencoded”。
context 为所有 AJAX 相关的回调函数规定 “this” 值。
converters 包含数据类型到数据类型转换器的对象。每个转换器的值都是一个函数,用于返回响应的转换值。 默认:{“* text”: window.String, “text html”: true, “text json”: jQuery.parseJSON, “text xml”: jQuery.parseXML}
crossDomain 如果要在同一域上强制跨域请求(如 JSONP),请将跨域的值设置为 。例如,这允许服务器端重定向到另一个域。默认:false for same-domain requests, true for cross-domain requests
data 规定要发送到服务器的数据。
dataFilter(data,type) 用于处理 XMLHttpRequest 原始响应数据的函数。
dataType 预期的服务器响应的数据类型。
error(xhr,status,error) 如果请求失败要运行的函数。
global 布尔值,规定是否为请求触发全局 AJAX 事件处理程序。默认是 true。
headers 其他标头键/值对的对象,要与使用 XMLHttpRequest 传输的请求一起发送。始终添加标头,但可以在此处更改其默认值。还可以从函数内部覆盖设置中的值。默认:{}
ifModified 布尔值,规定是否仅在最后一次请求以来响应发生改变时才请求成功。默认是 false。
isLocal 允许将当前环境识别为“本地”(例如文件系统),即使 jQuery 默认不将其识别为“本地”。以下协议当前被识别为本地协议:、 和 。如果设置需要修改,建议在方法中修改一次。默认:depends on current location protocol
jsonp 在一个 jsonp 中重写回调函数的字符串。
jsonpCallback 在一个 jsonp 中规定回调函数的名称。
password 规定在 HTTP 访问认证请求中使用的密码。
processData 布尔值,规定通过请求发送的数据是否转换为查询字符串。默认是 true。
scriptCharset 规定请求的字符集。
statusCode 当响应具有相应代码时要调用的数字 HTTP 代码和函数的对象。如果请求成功,状态码函数采用与成功回调相同的参数;例如statusCode: {404: function() {alert( "page not found" );}}如果它导致错误(包括 3xx 重定向),它们采用与回调相同的参数。error
success(result,status,xhr) 当请求成功时运行的函数。
timeout 设置本地的请求超时时间(以毫秒计)。
traditional 布尔值,规定是否使用参数序列化的传统样式。
type 规定请求的类型(GET 或 POST)。
url 规定发送请求的 URL。默认是当前页面。
username 规定在 HTTP 访问认证请求中使用的用户名。
xhr 用于创建 XMLHttpRequest 对象的函数。

jQuery.Ajax

jQuery.Ajax中文文档

axios中的Ajax

引入axios

1
2
3
4
5
6
// cdn
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
//或
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
// npm
npm install axios

发送请求

  • GET

1
2
3
4
5
6
7
8
9
axios.get('http://127.0.0.1:8080/login',{
params: {
user: '123456',
passwd: '123456'
},
headers: {
'Content-type': 'application/x-www-form-urlencoded'
},
})
  • POST

1
2
3
4
5
6
7
8
9
10
11
12
13
14
axios.post('http://127.0.0.1:8080/login', 
{
val1: "1234",
val2: "name"
},
{
params: {
user: '123456',
passwd: '123456'
},
headers: {
'Content-type': 'application/x-www-form-urlencoded'
}
})

通用方法发送Ajax请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
axios({
method: "POST",
url: 'login',
params: {
user: '123456',
passwd: '123456'
},
headers: {
'Content-type': 'application/x-www-form-urlencoded'
},
data: {
val1: "1234",
val2: "name"
},
})

请求配置

请求配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
{
// `url` 是用于请求的服务器 URL
url: '/user',

// `method` 是创建请求时使用的方法
method: 'get', // 默认值

// `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
// 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
baseURL: 'https://some-domain.com/api/',

// `transformRequest` 允许在向服务器发送前,修改请求数据
// 它只能用于 'PUT', 'POST' 和 'PATCH' 这几个请求方法
// 数组中最后一个函数必须返回一个字符串, 一个Buffer实例,ArrayBuffer,FormData,或 Stream
// 你可以修改请求头。
transformRequest: [function (data, headers) {
// 对发送的 data 进行任意转换处理

return data;
}],

// `transformResponse` 在传递给 then/catch 前,允许修改响应数据
transformResponse: [function (data) {
// 对接收的 data 进行任意转换处理

return data;
}],

// 自定义请求头
headers: {'X-Requested-With': 'XMLHttpRequest'},

// `params` 是与请求一起发送的 URL 参数
// 必须是一个简单对象或 URLSearchParams 对象
params: {
ID: 12345
},

// `paramsSerializer`是可选方法,主要用于序列化`params`
// (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
paramsSerializer: function (params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
},

// `data` 是作为请求体被发送的数据
// 仅适用 'PUT', 'POST', 'DELETE 和 'PATCH' 请求方法
// 在没有设置 `transformRequest` 时,则必须是以下类型之一:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 浏览器专属: FormData, File, Blob
// - Node 专属: Stream, Buffer
data: {
firstName: 'Fred'
},

// 发送请求体数据的可选语法
// 请求方式 post
// 只有 value 会被发送,key 则不会
data: 'Country=Brasil&City=Belo Horizonte',

// `timeout` 指定请求超时的毫秒数。
// 如果请求时间超过 `timeout` 的值,则请求会被中断
timeout: 1000, // 默认值是 `0` (永不超时)

// `withCredentials` 表示跨域请求时是否需要使用凭证
withCredentials: false, // default

// `adapter` 允许自定义处理请求,这使测试更加容易。
// 返回一个 promise 并提供一个有效的响应 (参见 lib/adapters/README.md)。
adapter: function (config) {
/* ... */
},

// `auth` HTTP Basic Auth
auth: {
username: 'janedoe',
password: 's00pers3cret'
},

// `responseType` 表示浏览器将要响应的数据类型
// 选项包括: 'arraybuffer', 'document', 'json', 'text', 'stream'
// 浏览器专属:'blob'
responseType: 'json', // 默认值

// `responseEncoding` 表示用于解码响应的编码 (Node.js 专属)
// 注意:忽略 `responseType` 的值为 'stream',或者是客户端请求
// Note: Ignored for `responseType` of 'stream' or client-side requests
responseEncoding: 'utf8', // 默认值

// `xsrfCookieName` 是 xsrf token 的值,被用作 cookie 的名称
xsrfCookieName: 'XSRF-TOKEN', // 默认值

// `xsrfHeaderName` 是带有 xsrf token 值的http 请求头名称
xsrfHeaderName: 'X-XSRF-TOKEN', // 默认值

// `onUploadProgress` 允许为上传处理进度事件
// 浏览器专属
onUploadProgress: function (progressEvent) {
// 处理原生进度事件
},

// `onDownloadProgress` 允许为下载处理进度事件
// 浏览器专属
onDownloadProgress: function (progressEvent) {
// 处理原生进度事件
},

// `maxContentLength` 定义了node.js中允许的HTTP响应内容的最大字节数
maxContentLength: 2000,

// `maxBodyLength`(仅Node)定义允许的http请求内容的最大字节数
maxBodyLength: 2000,

// `validateStatus` 定义了对于给定的 HTTP状态码是 resolve 还是 reject promise。
// 如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),
// 则promise 将会 resolved,否则是 rejected。
validateStatus: function (status) {
return status >= 200 && status < 300; // 默认值
},

// `maxRedirects` 定义了在node.js中要遵循的最大重定向数。
// 如果设置为0,则不会进行重定向
maxRedirects: 5, // 默认值

// `socketPath` 定义了在node.js中使用的UNIX套接字。
// e.g. '/var/run/docker.sock' 发送请求到 docker 守护进程。
// 只能指定 `socketPath` 或 `proxy` 。
// 若都指定,这使用 `socketPath` 。
socketPath: null, // default

// `httpAgent` and `httpsAgent` define a custom agent to be used when performing http
// and https requests, respectively, in node.js. This allows options to be added like
// `keepAlive` that are not enabled by default.
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),

// `proxy` 定义了代理服务器的主机名,端口和协议。
// 您可以使用常规的`http_proxy` 和 `https_proxy` 环境变量。
// 使用 `false` 可以禁用代理功能,同时环境变量也会被忽略。
// `auth`表示应使用HTTP Basic auth连接到代理,并且提供凭据。
// 这将设置一个 `Proxy-Authorization` 请求头,它会覆盖 `headers` 中已存在的自定义 `Proxy-Authorization` 请求头。
// 如果代理服务器使用 HTTPS,则必须设置 protocol 为`https`
proxy: {
protocol: 'https',
host: '127.0.0.1',
port: 9000,
auth: {
username: 'mikeymike',
password: 'rapunz3l'
}
},

// see https://axios-http.com/zh/docs/cancellation
cancelToken: new CancelToken(function (cancel) {
}),

// `decompress` indicates whether or not the response body should be decompressed
// automatically. If set to `true` will also remove the 'content-encoding' header
// from the responses objects of all decompressed responses
// - Node only (XHR cannot turn off decompression)
decompress: true // 默认值

}

响应结构和处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
// `data` 由服务器提供的响应
data: {},

// `status` 来自服务器响应的 HTTP 状态码
status: 200,

// `statusText` 来自服务器响应的 HTTP 状态信息
statusText: 'OK',

// `headers` 服务器响应的头
headers: {},

// `config` 是为请求提供的配置信息
config: {},
// 'request'
// `request` is the request that generated this response
// It is the last ClientRequest instance in node.js (in redirects)
// and an XMLHttpRequest instance the browser
request: {}
}

使用 then 时,你将接收下面这样的响应 :

1
2
3
4
5
6
7
8
axios.get('/login')
.then(function(response) {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
});

跨域

同源策略

同源策略是一个重要的安全策略,它用于限制一个源的文档或者它加载的脚本如何能与另一个源的资源进行交互。

它能帮助阻隔恶意文档,减少可能被攻击的媒介。

JSONP方案

通过网页中的一些标签,如 img、iframe、script来解决。

1
<script src="http://127.0.0.1/data"></script>

CORS方案

跨源资源共享(CORS,或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其他源(域、协议或端口),使得浏览器允许这些源访问加载自己的资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的“预检”请求。在预检中,浏览器发送的头中标示有 HTTP 方法和真实请求中会用到的头。

1
2
3
// 设置响应头
setHeader("Access-Control-Allow-Origin","*") //允许全部
setHeader("Access-Control-Allow-Origin","http://127.0.0.1:8080") //允许 http://127.0.0.1:8080