diff --git a/src/utils/request.js b/src/utils/request.js index 405acfc..a326f4e 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -25,6 +25,8 @@ service.interceptors.request.use( // 响应拦截器 service.interceptors.response.use( + + // 接口请求返回状态码是200,进入第一个 response => { const token = response.headers['Authorization']; if (token) { @@ -35,35 +37,33 @@ service.interceptors.response.use( error => { const resData = error.response?.data; const status = error.response?.status; + console.log("返回状态码", status); + // 1. 判定是否为 Token 相关的认证错误 // 包含 500 状态码且消息含有 token 字样(如 decode 失败、过期等) - if (status === 500 && resData?.message && /token/i.test(resData.message)) { - + if (status === 401) { + if (!isRelogging) { isRelogging = true; // 锁定 localStorage.removeItem('token'); // 清除用户信息,防止 UserView.vue 的 computed 报错 - localStorage.removeItem('user_info'); - + localStorage.removeItem('user_info'); + ElMessage.error('登录已失效,请重新登录'); router.push('/login').then(() => { // 2. 延迟解锁,确保页面跳转期间的所有并发请求都已返回并被此拦截器捕获 setTimeout(() => { isRelogging = false; - }, 3000); + }, 3000); }); } - // 3. 【关键】无论是否是第一个请求,只要是 Token 错误,都返回 Pending Promise - // 这会阻止组件内的 catch 块执行,从而消失“加载列表失败”等弹窗 return new Promise(() => { }); } - // 2. 处理非 Token 错误的普通报错(如网络断开、真正的服务器崩溃等) - // 只有不符合上面 Token 错误条件的请求才会走到这里 const msg = resData?.message || '服务器响应异常'; ElMessage.error(msg); return Promise.reject(error);