fix(auth): 登录页无限重载闪屏 —— 401 在 /login 上仍整页跳转导致死循环
=== 现象 === 打开 /login 页面一直加载、闪屏,无法登录。 线上访问日志:10 分钟内 /api/v1/system/license 被请求 **1566 次,全部 401**(约 2.6 次/秒)。 === 根因(三处叠加)=== 1) LicenseProvider 挂在 App 根部,包住**所有**路由(含 /login), 挂载即请求鉴权接口 /system/license;登录页没有 token → 401。 2) http.ts 的 redirectToLogin() 在已处于 /login 时仍然执行 window.location.href = '/login' —— **给 href 赋同值也会整页重载**。 3) 重载 → App 重新挂载 → LicenseProvider 再请求 → 再 401 → 再重载。 形成"请求→401→整页重载→请求"的死循环,用户看到的就是转圈+闪屏。 === 修复(三处,防御性叠加)=== 1) useLicense:没有 accessToken 时**不请求**;有 token 才拉。 并用 1 秒一次的低成本探测(只读 localStorage,不发请求)在登录成功 (token 出现)后补拉一次,避免登录后授权状态缺失。 2) licenseApi.status 使用 silent: true —— 401 不触发"清凭证+跳登录"的全局副作用。 3) redirectToLogin:已在 /login 时直接 return,不再重载页面。 === 验证 === tsc 通过;发布后 /login 不再产生 401 轮询(见发布后回归)
This commit is contained in:
1 parent
f02b1daee1
commit
f91078f814
3 files changed
+60
-12
No files matched your search
@@ -73,14 +73,16 @@ let redirecting = false;
|
||||
/** 清凭证并防抖跳转登录(并发失效只产生一次跳转,携带当前路径供回跳) */
|
||||
function redirectToLogin(): void {
|
||||
clearAuth();
|
||||
// 已经在登录页就**不要再跳**:给 location.href 赋同值也会触发整页重载,
|
||||
// 而重载会重新挂载组件、再发一次需要鉴权的请求 → 又 401 → 再重载。
|
||||
// 这正是登录页"一直加载 + 闪屏"的根本原因(实测 10 分钟 1566 次 401)。
|
||||
if (window.location.pathname.startsWith('/login')) {
|
||||
return;
|
||||
}
|
||||
if (redirecting) return;
|
||||
redirecting = true;
|
||||
const current = window.location.pathname + window.location.search;
|
||||
const target =
|
||||
current.startsWith('/login')
|
||||
? '/login'
|
||||
: `/login?redirect=${encodeURIComponent(current)}`;
|
||||
window.location.href = target;
|
||||
window.location.href = `/login?redirect=${encodeURIComponent(current)}`;
|
||||
}
|
||||
|
||||
/** 单次 HTTP 往返:组头、超时、取消、解包。401 以 ApiError(status=401) 抛出,由上层统一处理 */
|
||||
|
||||
Reference in new issue
Block a user