核心是快速感知、统一拦截、平滑引导:以后端返回401为唯一可信信号,在axios拦截器中清除凭证并跳转登录页(带redirect参数),配合防抖避免重复登出,全程依赖服务端响应而非前端时间判断。

在 JavaScript 接口调用中处理会话过期异常,核心是识别服务器返回的特定状态(如 401 Unauthorized 或自定义错误码),并触发统一的登出或跳转登录逻辑,避免后续请求反复失败。
识别会话过期响应
服务器通常通过以下方式标识会话过期:
- HTTP 状态码为 401(标准语义)或 403(部分系统用此表示权限失效)
- 响应体中包含明确字段,例如:
{"code": 1001, "message": "登录已过期"}或{"success": false, "error": "SESSION_EXPIRED"} - 响应头中携带特殊标识,如
X-Session-Expired: true
建议前后端提前约定一种主判断方式(推荐优先用 HTTP 状态码 + 统一业务码),避免多条件混用导致逻辑混乱。
在请求层统一拦截处理
使用 Axios、Fetch 封装或自研请求库,在发起请求后集中处理响应。以 Axios 为例:
axios.interceptors.response.use(
response => response,
error => {
const { response } = error;
// 检查是否为会话过期
if (
response?.status === 401 ||
(response?.data?.code === 1001 && /expired|login|auth/i.test(response.data.message))
) {
// 清除本地凭证(token、sessionStorage 等)
localStorage.removeItem('auth_token');
sessionStorage.clear();
// 跳转登录页(保留当前 URL 用于登录后回跳)
const redirect = encodeURIComponent(window.location.href);
window.location.href = `/login?redirect=${redirect}`;
return Promise.reject(new Error('Session expired'));
}
return Promise.reject(error);
}
);
防止重复登出和页面闪退
多个并发请求同时收到 401 时,可能触发多次跳转或清除操作。可加一层防抖控制:
- 用一个布尔变量(如
isLoggingOut)标记登出流程是否已启动 - 首次检测到 401 时设为 true,执行清理与跳转;后续 401 直接忽略
- 也可用 Promise 缓存登出过程,让所有等待中的请求 await 同一个登出 Promise
前端主动校验会话有效性(可选增强)
在关键操作前(如进入后台首页、提交表单),可先发一个轻量接口(如 /api/v1/auth/validate)确认 token 是否仍有效。但注意:这会增加一次请求开销,适合对体验要求高、且服务端不总返回准确 401 的场景。
不复杂但容易忽略的是——确保登录页本身不校验会话,且所有静态资源(如 CSS、图标)不走鉴权路由,否则可能陷入“因加载失败而无法打开登录页”的死循环。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











