VueJS下Axios Interceptors无法接收401响应问题排查
Axios响应拦截器不触发及401拦截实现方案
响应拦截器不触发的常见原因及修复
- 未统一使用配置了拦截器的axios实例:你当前直接修改全局axios的配置,若项目中其他模块导入axios时未加载你写的这个配置文件,拦截器就不会生效。推荐改为创建独立的自定义axios实例统一管理,避免全局污染。
- 请求错误未被捕获:如果请求返回4xx/5xx状态码,调用请求方法时需要搭配
catch或者try/catch捕获错误,否则错误会被静默吞掉,看起来像响应拦截器未执行。 - 跨域/网络故障导致请求根本未收到响应:浏览器跨域限制、网络断开时请求无法到达服务端也拿不到响应,自然不会触发响应拦截器,可先打开浏览器控制台Network面板确认请求是否正常得到响应。
修复后支持401刷新token的配置代码
import axios from "axios"; // 创建独立的axios实例,所有请求统一用这个实例调用 const request = axios.create({ baseURL: "https://btk7dl15c9.api.quickmocker.com", timeout: 10000 }); // 防止多个401请求重复刷新token的锁 let isRefreshing = false; // 存储401后待重发的请求 let retryRequests = []; request.interceptors.request.use( async (config) => { console.log("request ok"); // 这里可以统一加请求头比如Authorization const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, (error) => { console.log("request error"); return Promise.reject(error); } ); request.interceptors.response.use( (response) => { console.log("response ok"); return response.data; }, async (error) => { console.log("response error", error); const { config, response } = error; // 有响应且状态码为401时处理刷新逻辑 if (response && response.status === 401) { if (!isRefreshing) { isRefreshing = true; try { // 调用刷新token的接口,这里替换成你实际的刷新接口 const refreshRes = await request.post('/refresh-token', { refreshToken: localStorage.getItem('refreshToken') }); const { token, newRefreshToken } = refreshRes.data; // 更新本地存储的token localStorage.setItem('token', token); localStorage.setItem('refreshToken', newRefreshToken); // 修改待重发请求的header config.headers.Authorization = `Bearer ${token}`; // 执行所有待重发的请求 retryRequests.forEach(cb => cb(token)); retryRequests = []; // 重发当前401的请求 return request(config); } catch (refreshError) { // 刷新失败,清空token跳转到登录页 localStorage.removeItem('token'); localStorage.removeItem('refreshToken'); window.location.href = '/login'; return Promise.reject(refreshError); } finally { isRefreshing = false; } } else { // 正在刷新token,把当前请求加入待重发队列 return new Promise(resolve => { retryRequests.push(token => { config.headers.Authorization = `Bearer ${token}`; resolve(request(config)); }) }) } } return Promise.reject(error); } ); export default { methods: { axiosPost(url, data) { return request.post(url, data); } } };
调用示例
// 调用时必须捕获错误,否则异常会静默 this.axiosPost('/your-api-path', {key: 'value'}) .then(res => { console.log('请求成功', res) }) .catch(err => { console.log('请求失败', err) }) // async/await写法 async function fetchData() { try { const res = await this.axiosPost('/your-api-path', {key: 'value'}) console.log('请求成功', res) } catch (err) { console.log('请求失败', err) } }
内容的提问来源于stack exchange,提问作者tkamstra
相关产品推荐
相关产品推荐

