问题出现的原因是Axios的响应拦截器会在每一次请求时都执行,当需要刷新令牌的时候,也会执行响应拦截器,导致死循环的问题。
要解决这个问题,需要在响应拦截器中加入一个判断条件,判断当前请求是否已经在刷新令牌的过程中,如果是,则不进行刷新令牌的操作。
以下是示例代码:
let isRefreshing = false
let failedQueue = []
axios.interceptors.response.use(
(response) => {
return response
},
async (error) => {
const originalRequest = error.config
if (error.response.status === 401 && !originalRequest._retry) {
if (isRefreshing) {
// 如果正在刷新令牌,则将当前请求加入失败队列
return new Promise(function (resolve, reject) {
failedQueue.push({ resolve, reject })
}).then(() => {
return axios(originalRequest)
}).catch((error) => {
return Promise.reject(error)
})
}
originalRequest._retry = true
isRefreshing = true
// 调用刷新令牌 API
const response = await refreshToken()
if (response.status === 200) {
// 刷新令牌成功
isRefreshing = false
// 更新令牌
saveToken(response.data)
// 重新执行失败队列中的请求
failedQueue.forEach((item) => item.resolve(axios(originalRequest)))
failedQueue = []
return axios(originalRequest)
} else {
// 刷新令牌失败
isRefreshing = false
failedQueue.forEach((item) => item.reject(error))
failedQueue = []
return Promise.reject(error)
}
}
return Promise.reject(error)
}
)
以上代码实现了一个简单的令牌刷新机制,能够有效地避