在 http 拦截器中使用 observable 时,请求被无限触发

Request is being fired infinitely when using observable in http interceptor

我对依赖于 observable 的 http 拦截器有疑问。整个事情以无限循环结束,一遍又一遍地调用相同的 URL。 但是,我搜索了与我的类似的其他解决方案(参见 Async HTTP Interceptors with Angular 4.3),除了不同的 rxjs 版本外,我看不出有什么大的不同。拦截器如下所示:

@Injectable()
export class MyHttpInterceptor implements HttpInterceptor {

  constructor(private loginSvc: LoginService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {    
    return this.loginSvc.currentUser$.pipe(
      mergeMap(x => {
        if (x) {
          console.log("User is authenticated, usually I would add a bearer token to the request here...");
        }
        return next.handle(req);
      })
    );
  }
}

有人可以指出我在 Angular http 拦截器中犯的错误吗?您可以在此处查看整个工作示例:

https://stackblitz.com/edit/angular-cazgsa?file=src%2Fapp%2Fservices%2Fmy-http-interceptor.service.ts

设置如下:

  1. login.service.ts:该服务封装了认证用户。它通过一个 BehaviorSubject 和一个相应的 Observable 来做到这一点。最初,主题用 null 初始化,表示未登录用户。
  2. login.component.ts 第 17 行:一旦路由 /login 打开,我们就会模拟一个应该对用户进行身份验证的请求。该请求只是 returns 来自模拟成功登录的 jsonplaceholder 的用户。
  3. 我们正在通过 LoginService 填充用户,以便所有感兴趣的各方/观察者都能了解新登录的用户。 http 拦截器就是这些感兴趣的团体之一。

为了重现该问题,请打开 StackBlitz 上的 http 拦截器并取消注释其中所述的行。在开发人员控制台中,您会看到无限循环中出现的重复日志消息。 注意:如果等待时间过长,会导致浏览器选项卡崩溃/window!因此,如果您在能够重现问题后取消注释,请快速再次注释掉这些行! 在 StackBlitz 上,您可以简单地使用快捷键 STRG + / 来切换多行注释!

提前致谢!

我调试了你的代码。

当您的 http 请求完成时,您将新值推送给用户主题(方法 signIn)。您的中断流依赖于 currentUser$,一旦新用户值到达,中断器将重新开始。我修复了中断器以避免此问题,并根据当前用户停止。

https://stackblitz.com/edit/angular-vbca4p?file=src%2Fapp%2Fservices%2Fmy-http-interceptor.service.ts