核心是快速感知、统一拦截、平滑引导:以后端返回401为唯一可信信号,在Axios拦截器中清除凭证并跳转登录页(带redirect参数),配合路由守卫提前过滤、visibilitychange时轻量探测、模态框温和提示,全程依赖服务端响应而非前端时间判断。

用 401 响应作为唯一可信失效信号
后端必须对所有受保护接口,在 Session 过期时返回标准 HTTP 401 Unauthorized(或统一 JSON 结构如 { "code": 401, "msg": "登录已过期" })。前端绝不依赖本地时间戳、token 过期字段等自行判断——客户端时间不准、时区混乱、Token 签发逻辑变动都会导致误判。
在 Axios 或 Fetch 拦截器中集中处理:
- 检查响应状态码 === 401,或解析 body 后
data?.code === 401 - 立即清除凭证:
localStorage.removeItem('token')、sessionStorage.clear() - 跳转登录页,并附带当前路径用于回跳:
location.href = '/login?redirect=' + encodeURIComponent(location.pathname)
路由守卫提前过滤非法访问
用户直接输入 /dashboard 等受保护 URL 时,不能等接口报错才跳转,否则可能白屏或触发错误渲染。
在 Vue Router 的 router.beforeEach 或 React Router 的 useNavigate + 自定义 hook 中:
立即学习“Java免费学习笔记(深入)”;
- 读取
localStorage.getItem('token')或检查是否存在有效登录态标记 - 若为空或明显无效(如格式错误),直接
next('/login')或navigate('/login', { replace: true }) - 注意:这只是快速过滤层,不替代 401 拦截——最终以服务端响应为准
前台恢复时主动校验会话有效性
移动端切后台再切回、PC 浏览器切换标签页后重新聚焦,都可能已过期但前端尚未感知。
监听浏览器可见性变化:
document.addEventListener('visibilitychange', () => { if (!document.hidden) checkAuth(); })-
checkAuth()中可发起一个轻量认证接口(如/api/auth/status),成功则继续,失败则按 401 流程处理 - 避免在
visibilitychange中发敏感操作请求,只做状态探测
对用户操作做温和降级提示
正在编辑表单、阅读长文时突然跳转登录页,体验极差。
收到 401 后可改为弹出模态框:
- 文案:“登录状态已过期,请重新登录以保存当前操作”
- 按钮:“去登录”(跳转)和“稍后再说”(关闭弹窗,保留当前页)
- 点击“稍后再说”后,下次发起请求仍会拦截 401,再次提醒,形成渐进式引导


















