引言:
我们知道原生Ajax请求是基于XMLHttpRequest的,在本文中首先介绍下XMLHttpRequest的相关基本知识,然后基于Promise封装一个Ajax请求。
XMLHttpRequest简介
这部分的内容主要参考MDN上对于XMLHttpRequest的介绍
XMLHttpRequest是什么?
简单一句话,浏览器是通过XMLHttpRequest与服务器进行通信的,包括现在常用的axios库,都是基于XMLHttpRequest的。
一些常用的方法和属性
open方法
- 初始化一个请求
- 用法:xhr.open(method, url, flag)
- method: Http方法:包括 get、post、header、put、delete等
- url: 要请求的服务地址
- flag: 可选,是否进行异步操作 默认true(异步)
setRequestHeader方法
- 设置http请求头的方法
- 用法: xhr.setRequestHeader(header, value)
- header: 属性名
- value:属性值
send方法
- 发送http请求
- 用法: xhr.send(params) params:发送的数据
readyState属性
- 表示XMLHttpRequest实例当前所处的状态
- 解释
| 值 | 描述 |
|---|---|
| 0 | 代理被创建,但尚未open |
| 1 | open()方法已经被调用 |
| 2 | send()方法被调用 |
| 3 | 下载中 |
| 4 | 下载操作完成 |
state属性
- XMLHttpRequest响应的数字状态码,也就是http状态码
onreadstatechange 属性
- 返回一个回调函数
- 表示readState变化,callback
封装Ajax
Ajax请求五步走
发送一个ajax请求,总共需要以下五个步骤:
- 创建XMLHttpRequest对象
- 创建http请求,与服务器连接
- 设置请求头
- 发送请求
- 响应http状态变化的函数
来段代码,对上面的步骤进行一个说明
// 1.实例化XMLHttpRequest对象
var xhr = new XMLHttpRequest();
// 2.创建http请求 xhr.open(method, url, flag true同步)
xhr.open('get', 'http://localhost:2000/name', true);
// 3.设置请求头
xhr.setRequestHeader('Contend-Type', "application/json;charset=UTF-8");
// 4.发送请求
xhr.send(null);
// 处理post请求的参数封装
// var param = {
// name : 'shaoyan',
// age: 20
// }
// xhr.send(JSON.stringify(param))
// 5. 响应状态变化
xhr.onreadystatechange = function(){
if(xhr.readyState ==4 && xhr.status === 200){
console.log(JSON.parse(xhr.response) )
}
}
基于Promise封装Ajax请求
基于上面的五步走,采用Promise,来封装一个方法,我会在代码中加注释做说明。
/**
* 封装一个链式ajax请求
* @param obj 传入的参数
*/
function ajaxHttp(obj){
//默认参数, 如果没传的话用这个
let oriObj = {
method: 'get',
url: '/',
async: true,
data: null,
contentType: `application/json;charset=UTF-8`
}
// 将传入的参数与默认参数合并
let endObj = Object.assign({}, oriObj, obj)
// 封装成链式结构
return new Promise((resolve, reject)=> {
let {method, url, data, async, contentType} = endObj
// 1.实例化XMLHttpRequest
let xhr = new XMLHttpRequest()
// get方法的话对参数进行拼接成 ? name= '' & age = 这种形式
let isGet = method === 'get'? true: false
if(isGet && data){
let params = ''
for(let key in data){
params += `${key} = ${endObj.data[key]} &`
}
url += '?' + params.substring(0, params.length-1)
}
// 2. 创建http请求
xhr.send(method, url, async)
// 3. 设置请求头
xhr.setRequestHeader('content-type', contentType)
// 4. 发送数据
if(!data){
xhr.send(null)
}else{
JSON.stringify(data)
}
// 5. 响应http状态变化
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4){
if(xhr.status === 200){
resolve(xhr.response)
}else{
reject('错误')
}
}else{
reject('错误')
}
}
})
}
这样, 我们就封装了一个简单的ajax请求,使用的时候可以采用链式调用,如下例子,是不是和axios的基本使用方法很像:
ajaxHttp({
method: 'get',
url: `http://localhost:2000/name`,
data: null
}).then((data)=>{
console.log(data)
}).catch((res)=>{
console.log(res)
})