核心:
1:在axios请求之前做拦截;
2:axios请求拦截中设置cancelToken;
3:页面跳转取消上一个页面所有的请求。
在axios.js中
请求拦截中:
**
* 请求拦截中 的config.cancelToken
*
* 在页面跳转 (页面路由改变的时候) 在APP.js中 UNSAFE_componentWillReceiveProps
*
* 执行eventBus['cancelTokenList']数组中的每个对象的cancel函数
*
* eventBus为一个对象,在外界一个js中建立一个对象导出
* 分别在axios.js和APP.js中引入,命名为eventBus;
*/
instance.interceptors.request.use(config => {
// Do something before request is sent
//=======================================================================
config.cancelToken = new axios.CancelToken(cancel => {
// cancel函数标识 用来和响应请求作比较 看是否已经请求过,是 则过滤
let cancelTokenFlag = new Date().getTime() + Math.random() * 2
//添加自定义属性
config['cancelTokenFlag'] = cancelTokenFlag;
//添加自定义属性
eventBus['cancelTokenList'] = eventBus['cancelTokenList'] ? [...eventBus['cancelTokenList'], {
cancel, cancelTokenFlag }] : [{
cancel, cancelTokenFlag }]
})
//=======================================================================
return config;
}, error => {
return Promise.reject(error);
});
axios的响应拦截:
instance.interceptors.response.use(function (response) {
let {
data: {
code } } = response
if (code === 403) {
goLoginFun()
return {
}
}
// 过滤掉已经成功请求的xmlhttprequest
//重点
//=================================================
eventBus['cancelTokenList'] = eventBus['cancelTokenList'].filter(i => i.cancelTokenFlag === response.config['cancelTokenFlag'])
//=================================================
return response
}, function (error) {
// console.log(error.response, 'error1')
// console.log(error.request, 'error2')
// console.log(error, 'error3')
//打断因为请求主动断开导致页面接口报错 返回一个空Promise
if (axios.isCancel(error)) {
// error === '跳转页面,主动放弃请求上一个页面接口数据'
console.log(error)
// 中断promise链接
return new Promise(() => {
})
}
//跳转到登录页面
if (error.response) {
if (error.response.status == 403) {
goLoginFun()
}
return Promise.reject(error.response)
} else if (error.request) {
if (error.request.status == 403) {
goLoginFun()
}
return Promise.reject(error.request)
} else {
goLoginFun()
return Promise.reject(error.message)
}
})
APP.JS:
UNSAFE_componentWillReceiveProps生命周期钩子:
UNSAFE_componentWillReceiveProps(nextProps) {
// 判断跳转路由不等于当前路由
if (nextProps.location.pathname !== this.props.location.pathname) {
eventBus['cancelTokenList'] = eventBus['cancelTokenList'] ? eventBus['cancelTokenList'] : []
for (let i = 0; i < eventBus['cancelTokenList'].length; i++) {
eventBus['cancelTokenList'][i].cancel('跳转页面,主动放弃请求上一个页面接口数据')
}
eventBus['cancelTokenList'] = eventBus['cancelTokenList'].splice(0);
// 清空缓存跳转 路由改变触发
if (!localStorage.getItem('username')) {
message.warning("登录已过期,请重新登录!")
this.props.history.push('/login')
}
}
}