前言
需求背景:不同的接口需求,axios
的拦截器配置也不一样。比如,有的业务场景需要axios
有超时跳转到登录页面,有的业务场景无需该提示,那么该如何编写axios
,最初,我将axios
的response
的拦截器放在函数内,如下代码所示:
function genHcParams() {
let hcParams = {}
let axios = service
if (window.globalApi) {
if (globalApi.useAxiosInterceptors) {
axios.interceptors.response.use(response => {
if (response && response.headers) {
const json = response.data
if (json && json.status) {
if (json.status === 'jump') {
if (json.result.redirect) {
setTimeout(() => {
window.location.href = json.result.redirect
}, 200)
}
return
}
}
if (json) {
return json
}
return response
} else if (response) {
return response
}
})
} else {
axios.interceptors.response.use(response => {
return response.data
})
}
if (globalApi.isHc || globalApi.isLocalSetZz) {
hcParams.ak = 'ebf48ecaa1fd436fa3d40c4600aa051f'
axios = serviceHc
} else if (globalApi.isMars) {
} else {
hcParams.coordinate = 'wgs84'
}
}
return {
hcParams,
axios
}
可是遇到一个问题,后端只返回一次接口数据,为何axios.interceptors.response.use
里面的函数会被多次执行?
原因
若你使用use
,就像Node.js
里的use
那样,会不断地往axios
对象添加interceptors
,由于我将该拦截器放在函数内,只要函数被执行,则会再次将拦截器函数增添到axios
对象上。
所以,推荐的办法是,将拦截器放在函数外,可我的需求决定了,我必须将它放在函数内,那么该如何解决呢?
方法
添加该文件内的唯一变量标识符let axiosInterceptor = undefined
,只要拦截器存在,则不会继续添加,部分代码如下所示:
let axiosInterceptor = undefined;
...
if (globalApi.useAxiosInterceptors) {
if (axiosInterceptor === undefined) {
axiosInterceptor = axios.interceptors.response.use(response => {
if (response && response.headers) {
const json = response.data
if (json && json.status) {
if (json.status === 'jump') {
if (json.result.redirect) {
setTimeout(() => {
window.location.href = json.result.redirect
}, 200)
}
return
}
}
if (json) {
return json
}
return response
} else if (response) {
return response
}
})
}
} else {
if (axiosInterceptor === undefined) {
axiosInterceptor = axios.interceptors.response.use(response => {
if (response && response.data) return response.data
})
}
}
...