原生JS封装jQuery的AJAX

基本功能

设置请求request

第一步 let request = new XMLHttpRequest()
第一部分:
request.open('GET', '/xxx')
第二部分:(不能设置User-Agent,会报错)
request.setRequestHeader('Content-Type', 'x-www-form-urlencoded')
第四部分:
request.send('a=0&b=1')

获取响应response

第一部分:获取HTTP状态
request.status //200
request.statusText //OK

第二部分:获取响应header
request.getAllResponseHeaders() //获取第二部分所有内容
request.getResponseHeader('Content-Type') //获取Content-Type 的内容

第四部分:
request.responseText()


封装jQuery.ajax

初始版本

封装:

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
window.jQuery.ajax = function(options){
let url = options.url
let method = options.method
let body = options.body
let successFn = options.successFn
let failFn = options.failFn
let headers = options.headers

let request = new XMLHttpRequest()
request.open(method, url) //初始化请求
for(let key in headers){
let value = headers[key]
request.setRequestHeader(key, value)
}
request.onreadystatechange = () =>{
if(request.readyState === 4){
if(request.status >= 200 && request.status <= 300){
successFn.call(undefined, request.responseText)
}else if(request.status >= 400){
failFn.call(undefined, request)
}
}
}
request.send(body) //发送请求
}

window.$ = window.jQuery

调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
myButton.addEventListener('click', (e) =>{
window.jQuery.ajax({
url: '/xxx',
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'allen': '23'
} ,
body: 'a=0&b=1',
successFn: (x) => {console.log(x)},
failFn: (x) => {
console.log(x)
console.log(x.statusText)
console.log(x.responseText) //请求失败也可以获取第四部分
}
})
})

此时代码很傻,下面来优化一下。


使用ES6语法解构赋值

ES6新语法之解构赋值,见MDN文档
优化后的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
window.jQuery.ajax = function({url, method, body, successFn, failFn, headers}){  //解构赋值语法
let request = new XMLHttpRequest()
request.open(method, url) //初始化请求
for(let key in headers){
let value = headers[key]
request.setRequestHeader(key, value)
}
request.onreadystatechange = () =>{
if(request.readyState === 4){
if(request.status >= 200 && request.status <= 300){
successFn.call(undefined, request.responseText)
}else if(request.status >= 400){
failFn.call(undefined, request)
}
}
}
request.send(body) //发送请求
}


使用promise优化

因为每个程序员的回调名不一样,你不看文档根本不知道这个库的函数名是什么,所以我们可以使用该方法不设置successFn、failFn这两个函数的函数名。
返回一个promise对象,传入的两个参数resolve、reject,分别代表成功时执行的内容和失败时执行的内容。

再次优化后的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
window.jQuery.ajax = function({url, method, body, headers}){
return new Promise(function(resolve, reject){ // 这行代码要记住
let request = new XMLHttpRequest()
request.open(method, url) //初始化请求
for(let key in headers){
let value = headers[key]
request.setRequestHeader(key, value)
}
request.onreadystatechange = () =>{
if(request.readyState === 4){
if(request.status >= 200 && request.status <= 300){
resolve.call(undefined, request.responseText)
}else if(request.status >= 400){
reject.call(undefined, request)
}
}
}
request.send(body) //发送请求
})
}

调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 window.jQuery.ajax({
url: '/xxx',
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'allen': '23'
}
}).then(
(responseText) => {
console.log(responseText);
return responseText;
},
(request) => {
console.log('error'); return 'error'
}
)

then返回也是promise对象,于是就有了链式操作。

jQuery本身的ajax方法

上面是我们模仿jQuery自己封装的ajax方法,下面来看看jQuery真正的ajax方法。
举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$.ajax({
url:'/xxx',
method: 'post',
dataType:'x-www-form-urlencoded',
data:'a=0&b=1',
success:(responseText)=>{console.log(responseText)},
error:(e)=>{console.log('error')}
})

$.ajax({
url:'/xxx',
method: 'post',
dataType:'json',
data:'a=0&b=1',
}).then(
(responseText)=>{console.log(responseText)},
(e)=>{console.log('error')}
)