如何处理Angular中不同async管道触发的重复401错误提示问题
问题原因
- 页面中两个
async管道各自绑定了独立的Observable(IssueObs$和AreaObs$),会触发两次独立的后端请求 - JWT过期时两次请求先后返回401状态码,拦截器的错误处理逻辑会被执行两次,因此出现重复提示
解决方案
推荐直接在拦截器侧加状态锁,从根源上避免重复执行401处理逻辑:
- 在拦截器类中新增一个状态标识,标记当前是否正在处理401错误
- 进入401分支时先判断标识,如果已经在处理中直接跳过逻辑,否则执行处理流程并锁定标识
修改后的拦截器代码参考:
// 拦截器类中新增状态属性 private isHandling401 = false; intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { return next.handle(request).pipe( timeout(10000), catchError(error => { if (error) { switch (error.status) { case 401: // 已经在处理401的话直接返回错误,不重复执行逻辑 if (this.isHandling401) { return throwError(error); } // 锁定状态 this.isHandling401 = true; if (error.error == null) { this.toastr.info("Session has ended!") this.accountService.logout(); } else { this.toastr.error(error.error) } this.dialogRef.closeAll(); this.router.navigateByUrl(''); // 如果业务需要支持不刷新页面重新登录,可以在跳转后重置状态 // setTimeout(() => this.isHandling401 = false, 2000); break; } } return throwError(error); }) ); }
可选补充方案
如果仅需要避免重复提示,也可以直接配置toastr的全局去重参数,在引入toastr模块时添加配置即可:
ToastrModule.forRoot({ preventDuplicates: true, // 其他自定义配置 })
该方案仅能屏蔽重复提示,还是会执行两次登出、跳转逻辑,不如状态锁方案彻底。
内容的提问来源于stack exchange,提问作者Taher El-hares
相关产品推荐
相关产品推荐

