核心机制
1. storage 事件监听(跨标签页同步)
javascript
window.addEventListener("storage", e => {
"userToken" !== e.key || !yc(e.newValue) || yc(e.oldValue) || (
// 检测到 token 被清空,触发登出
oF.j.next({ method: "beUnauthenticated", args: { navigateToSignIn: true, isBanned: false } })
)
});
-
yc函数判断值是否为空/null/undefined:javascript
let yc = e => { if (null === e || "" === e) return true; try { let t = JSON.parse(e); return null === t.value || void 0 === t.value || "" === t.value } catch { return false } }; -
当
newValue为空而oldValue非空时,触发beUnauthenticated,跳转到登录页。
2. API 响应拦截(服务端 token 失效)
在 HTTP 拦截器 onAfterResponse / onResponseError 中处理:
javascript
if (m.includes(r)) { // m = [v.V.MISSING_TOKEN, v.V.INVALID_TOKEN]
d.onTokenInvalid(); // 触发 beUnauthenticated
}
当后端返回 MISSING_TOKEN 或 INVALID_TOKEN 错误码时,自动调用登出逻辑。
3. 主动清除 token
登出函数 hB 中:
javascript
await (0, to.d9)(...); // 调用登出 API
n({ navigateToSignIn: true, isBanned: false }); // 触发 beUnauthenticated
4. 统一跳转逻辑 beUnauthenticated
javascript
function fi(e) {
let { navigateToSignIn: t, isBanned: n } = e;
w.y.setStorageUserToken(null); // 清空本地 token
// ... 清理其他状态 ...
t && fo(n ? nE.BANNED : nE.SIGN_IN); // 跳转到登录页或被封禁页
}
完整流程
| 触发场景 | 检测方式 | 动作 |
|---|---|---|
| 其他标签页登出 | storage 事件 |
当前标签页调用 beUnauthenticated |
| 后端返回 token 失效 | API 响应拦截 | 调用 beUnauthenticated |
| 用户主动点击登出 | 调用登出 API | 清除 token 并跳转 |
| 手动清空 localStorage | storage 事件(同一标签页不触发,但跨标签页会) |
同上 |
这样确保了无论 token 如何被置空或失效,前端都能可靠地跳转到登录页面。