要解决axios响应拦截器无法处理过期的refresh_token(401)的问题,可以使用以下代码示例:
// 创建axios实例
const axiosInstance = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000
});
// 定义变量用于存储是否正在刷新token的状态
let isRefreshing = false;
// 定义变量用于存储需要重新发送的请求
let refreshSubscribers = [];
// 添加请求拦截器
axiosInstance.interceptors.request.use(
config => {
// 在每个请求中添加token
const token = localStorage.getItem('access_token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
error => {
return Promise.reject(error);
}
);
// 添加响应拦截器
axiosInstance.interceptors.response.use(
response => {
return response;
},
error => {
const originalRequest = error.config;
// 处理refresh_token过期的401错误
if (error.response.status === 401 && !originalRequest._retry) {
if (isRefreshing) {
// 如果已经在刷新token,则将当前请求添加到刷新队列中
return new Promise((resolve, reject) => {
refreshSubscribers.push(token => {
originalRequest.headers.Authorization = `Bearer ${token}`;
resolve(axiosInstance(originalRequest));
});
});
}
// 设置正在刷新token的状态
isRefreshing = true;
// 发送刷新token的请求
const refreshToken = localStorage.getItem('refresh_token');
return new Promise((resolve, reject) => {
axiosInstance
.post('/refresh_token', { refresh_token: refreshToken })
.then(response => {
const { access_token } = response.data;
// 更新本地存储的token
localStorage.setItem('access_token', access_token);
localStorage.setItem('refresh_token', response.data.refresh_token);
// 更新请求的Authorization header
originalRequest.headers.Authorization = `Bearer ${access_token}`;
// 执行刷新队列中的请求
resolve(axiosInstance(originalRequest));
// 清空刷新队列
refreshSubscribers = [];
})
.catch(error => {
// 清空本地存储的token
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
// 跳转到登录页面
window.location.href = '/login';
reject(error);
})
.finally(() => {
// 重置刷新token的状态
isRefreshing = false;
});
});
}
return Promise.reject(error);
}
);
// 导出axios实例
export default axiosInstance;
在上述代码中,我们首先创建了一个axios实例axiosInstance
,然后添加了请求拦截器和响应拦截器。在请求拦截器中,我们在每个请求中添加了token。在响应拦截器中,我们处理了refresh_token过期的401错误。当收到401错误时,我们首先判断是否正在刷新token,如果是,则将当前请求添加到刷新队列中;如果不是,则发送刷新token的请求,并在请求成功后更新本地存储的token,并执行刷新队列中的请求。如果刷新token请求失败,则清空本地存储的token,跳转到登录页面。
使用上述代码示例,你可以在axios中处理过期的refresh_token,并且在刷新token时不会丢失任何请求。