这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战
一、拦截器
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);
});
除了axios,我们也可以给新创建的instance添加拦截器。
请求拦截器在发送请求之前执行,响应拦截器在收到请求之前之前执行。也就是在发送请求之前请求拦截器会将config做一些操作再发给服务器,服务器返回response后响应拦截器可以将response处理后再把数据返回。
知道了拦截的方式,那我们什么时候需要去拦截请求呢?
- config中的信息不符合服务器要求
- 发送网络请求时,需要在界面显示加载的图标
- 某些网络请求(比如登录token),需携带一些特殊信息
二、取消请求
基本流程
- 配置cancelToken对象
- 缓存用于取消请求的cancel函数
- 在后面特定时机调用cancel函数取消对象
- 在错误回调中判断如果error是cancel,做相应处理
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// executor 函数接收一个 cancel 函数作为参数
cancel = c;
})
});
cancel();
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 处理错误
}
});
// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');
三、源码分析
Axios与axios的区别?
- 语法上来说,axios不是Axios的实例
- 功能上来说,axios是Axios的实例,因为它具有Axios实例上的方法
- axios是Axios.prototype.request函数bind()返回的函数
- axios作为对象有Axios原型对象上的所有方法,有Axios对象上所有属性:defaults/interceptors
axios与instance的区别?
相同:本质上都是由createInstance()函数创建而成
- 都是一个能发任意请求的函数:request(config)
- 都有发特定请求的方法:get()/post()/put()/delete()
- 都有默认配置和拦截器属性:defaults/interceptors 不同:
- 默认匹配的值很可能不一样
- instance没有axios后面添加的一些方法:create()/all()/CancleToken()等等
axios/lib/core/Axios.js
axios/lib/axios.js
拦截器的执行顺序
首先,我们要明白,对于请求拦截器来说,后定义的拦截器先执行;而对于响应拦截器,先定义的拦截器先执行。
源码核心实现:axios/lib/core/Axios.js
举个栗子:
按顺序定义了四个拦截器:
请求拦截1(fullfilled1,rejected1)
请求拦截2(fullfilled2,rejected2)
响应拦截1(fullfilled111,rejected111)
响应拦截2(fullfilled222,rejected222)
requestInterceptorChain=[fullfilled2,rejected2,fullfilled1,rejected1]
responseInterceptorChain=[fullfilled111,rejected111,fullfilled222,rejected222]
chain=[fullfilled2,rejected2,fullfilled1,rejected1,dispatchRequest,undefined,fullfilled111,rejected111,fullfilled222,rejected222]
//promise = promise.then(chain.shift(), chain.shift())每次取出前两个,
promise执行顺序:
(fullfilled2,rejected2)-->(fullfilled1,rejected1)-->(dispatchRequest,undefined)-->(fullfilled111,rejected111)-->(fullfilled222,rejected222)
//最后返回promise,执行的就是请求的回调函数
总的来说,就是请求拦截器-->发送请求-->响应拦截器-->处理数据。
想了解上一篇axios内容,这里指路:axios入门篇