Vben5 token 过期后页面点不动,是并发 401 竞态
2026年4月27日
现象
token 过期时 dashboard 同时发起多个请求,全部返回 401。页面没有可见蒙版,但所有点击都失效。
根因
doReAuthenticate() 默认没有并发幂等保护。N 个并发 401 会触发 N 次登出流程,每次都会 resetAllStores() 并 router.replace(LOGIN_PATH)。竞态后果是 Pinia 多次清空导致渲染中的组件取到空值抛错,多个路由导航互相打断,而 Modal 的 backdrop 来不及随 v-model 卸载就被强制 reset,留下一个高 z-index 的透明 div 挡住所有点击。
修复
用 Promise 缓存包一层,保证并发只跑一次。
let reAuthenticatePromise: Promise<void> | null = null;
async function doReAuthenticate() {
if (reAuthenticatePromise) return reAuthenticatePromise;
reAuthenticatePromise = (async () => {
// 原有逻辑
})().finally(() => {
reAuthenticatePromise = null;
});
return reAuthenticatePromise;
}
排查方法
打开 F12 的 Elements 面板搜 mask,或者看 body > div 里有没有 z-index 大于 1000 的透明 div。Network 面板看是否一波 401 同时返回。