axios是什么?
基于promise的异步ajax请求库
axios有什么新特点?
拦截器的使用
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
const interceptorId = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(interceptorId);
/*
在axios对象属性中暴露出了一个interceptors这个属性对象,该对象有两个属性分别是request、response,这两个属性存分别对应请求前与请求后我们想做的一些操作,再调用use函数配置了两个函数进去。
*/
拦截器原理: 本质是一个顺序问题 请求拦截器-api请求-响应拦截器

var promise = Promise.resolve(config);
while (chain.length) {
promise = promise.then(chain.shift(), chain.shift());
}
取消请求的使用
1.excutor执行器函数是同步执行的,参数是用于取消当前请求的函数
2.当取消当前请求的函数被调用时,该请求会进入失败的流程,请求失败的error是Cancel对象类型,Cancel里面有message属性
let cancel //保存用于取消请求的函数
axios.get("/user",{
//new axios.CancelToken时得到一个函数
cancelToken:new axios.CancelToken(function excutor(c){
cancel = c; //准备发请求时先把函数取消当前请求的函数存储起来
}).then(response =>{
cancel = null; //如果请求完成就不要取消请求了
},error =>{
cancel = null;
})
})
取消请求的原理
request.abort()中断请求,并调用reject(cancel对象)将请求的状态该为失败。function CancelToken(excutor){
///...
let resolvePromise;
//为取消请求准备一个promise对象,并保存resolve函数
this.promise = new Promise(function promiseExecutor(resolve){
resolvePromise = resolve;
})
let token = this; //保存当前CancelToken对象
//立刻执行同步执行器,执行器外部定义,内部执行
excutor(function cancel(message){ //给excutor函数传参,参数为cancel函数
//....
//将token的reason指定为一个Cancel对象
token.reason = new Cancel(message);
resolvePromise(token.reason); //将取消请求的promise指定为成功,成功的值为reason
})
}
//取消请求部分的代码
if(config.cancelToken){
config.cancelToken.promise.then(function onCanceled(cancel){
request.abort();//中断请求
reject(cancel);
request = null'
})
}
new XMLHttpRequest()xhr.open(method,url,true) 默认async:true,参数是请求行xmr.send() 参数为字符串,可以是json对象字符串,也可以是urlencoded格式字符串xml.onreadystatechange 用于监听请求状态的改变,send是异步的readyState 0:初始 1:open()之后 2:send()之后 3:请求中 4:请求完成function axios({
url,
method='GET',
params={},
data={},
}){
return new Promise(resolve,reject){
//数据初始化操作
let query ='' ;
Object.keys(params).forEach(key => {
query += `${key}=${params[key]}&`
})
if(query){
query = query.substring(0,query.length-1);
url = url + '?' + query;
}
method = method.toUpperCase();
let xhr = new XMLHttpRequest() //创建xhr对象
xhr.open(url,method); //初始化请求
//状态监听,send是异步的
xhr.onreadystatechange = function(){
if(xhr.readyState !==4) return;
//请求完成
let {status,statusText} = xhr;
if (status>=200&&status<=299){
const response = {
data:JSON.parse(xhr.response),
status,
statusText,
}
resolve(response)
}else{
reject(new Error(`request error status is ${status}`))
}
}
switch(method){//发送请求
case 'GET' || 'DELETE':
xhr.send();
break;
case 'POST' || 'PUT':
xhr.setRequestHeader("Content-Type","application/json;charset=utf");
xhr.send(JSON.stringify(data));
}
}
}
| 方法/属性 | 描述 |
|---|---|
| readyState | 请求的状态 0:初始 1:open()之后 2:send()之后 3:请求中 4:请求完成 |
| onreadystatechange监视回调函数 | 绑定readyState改变的监听 on…当…时执行 |
| open(method,url[,async]) | 初始化一个请求 默认async:true,参数是请求行 |
| send(data) | 发送请求 参数为字符串,可以是json对象字符串,也可以是urlencoded格式字符串 |
| abort() | 中断请求 中断的是发出请求,还没结束的请求 |
| 状态码 | 类别 | 原因 |
|---|---|---|
| 2XX | 成功状态码 Success | 请求正常处理完毕 |
| 3XX | 重定向状态码 Redirection | 表示要完成请求,需要进一步操作(比如资源的url变了需要改变请求的url) |
| 4XX | 客服端错误状态码 Client Error | 服务器无法处理请求 |
| 5XX | 服务器错误状态码 Server Error | 服务器处理请求出错 |
3xx 重定向状态码
| 状态码 | 描述 | 理解 |
|---|---|---|
| 301 Moved Permanently | 永久重定向 | 请求的资源已经被移动到新的URI,返回信息会包括新的URI |
| 302 Found | 临时移动,请求的资源被临时移动了 | 希望本次使用新的URI访问 |
| 304 Not Modified | 服务器端资源未修改,可直接使用客户端未过期的缓存 | ★可以结合http缓存回答 |
4xx状态码 客户端错误状态码
| 状态码 | 描述 | 理解 |
|---|---|---|
| 400 Bad Request | 客户端请求的语法错误,服务器无法理解 | |
| 401 Unauthorized | 身份未认证 | 两种情况 1.服务端要求传递token信息,而实际发送请求时没有传递。 2.发送请求时有传递token到达服务器端,但由于时间比较久,这个token在服务器中已经过期了 |
| 403 Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求 | |
| 404 Not Found | 服务器上没有请求的资源 |
5xx状态码 服务器端错误状态码
| 状态码 | 描述 | 理解 |
|---|---|---|
| 500 Internal Server Error | 服务器内部错误,无法完成请求 | |
| 502 网关错误 | 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应 | |
| 503 Service Unavailable | 服务器暂时处于超负载或正在进行停机维护。现在无法处理请求 |
| 方法 | 描述 |
|---|---|
| head | 本质和get一样,但是响应中没有呈现数据,而是http的头信息,主要用来检查资源或超链接的有效性或是否可以可达、检查网页是否被串改或更新,获取头信息等,特别适用在有限的速度和带宽下。 |
| get | 从服务端获取数据 |
| post | 用于将数据发送到服务器来创建/更新资源 |
| put | 用于将数据发送到服务器来创建/更新资源 ,POST 和 PUT之间的区别多次调用相同的 PUT 请求将始终产生相同的结果,重复调用POST请求具有多次创建相同资源的副作用。 |
| delete | 删除指定的资源 |
| options | 获取http服务器支持的http请求方法,允许客户端查看服务器的性能,比如ajax跨域时的预检等。 |
对于跨域的非简单请求,浏览器会在正式通信之前,增加一次HTTP查询请求。使用 OPTIONS 方法发起一个预检(preflight)请求到服务器。
目的是为了知道服务器是否允许该请求
服务器成功响应预检请求后,浏览器才会发送真正的请求,并携带真实数据。
服务器的响应头
options请求的优化: 将预检请求的缓存后,以后每次浏览器正常的 CORS 请求,就都跟简单请求一样了。
| 类型 | 参数 | 性能问题 | 支持缓存 | 请求方式 |
|---|---|---|---|---|
| get请求 | 参数在url中,格式是key=value & key=value | GET请求只能进行url编码,参数的数据类型接收ASCII字符,回退无害 | get请求的响应结果会被浏览器缓存下来(一个get请求的路径对应一个资源) | 浏览器会把http header和data一并发送出去,服务器响应200 |
| post请求 | request body,在请求体当中发送 | post支持多种编码方式,参数的数据类型没有限制,回退再次提交请求 | 不支持 | 浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok |
GET产生一个TCP数据包;POST产生两个TCP数据包
GET 请求过程:
1.浏览器发起请求 TCP 连接(第一次握手)
2.服务器响应进行 TCP 连接(第二次握手)
3.浏览器确认,并发送 GET 请求头和数据(第三次握手)
4.服务器返回 200 OK响应
POST 请求过程:
1.浏览器发起请求 TCP 连接(第一次握手)
服务器响应进行 TCP 连接(第二次握手)
浏览器确认,并发送 POST 请求头(第三次握手)
服务器返回100 Continue响应
浏览器发送数据
服务器返回 200 OK响应
100:continue 客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。客户端应当继续发送请求的剩余部分