在http拦截器中使用Observable

时间:2019-01-09 20:20:10

标签: angular angular7 rxjs6 angular-http-interceptors

我有一个与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后,我们正在模拟一个对用户进行身份验证的请求。该请求只是从jsonplaceholder返回一个模拟成功登录的用户。
  3. 我们正在通过LoginService填充用户,以便所有感兴趣的参与者/观察者都可以了解到新登录的用户。这些感兴趣的参与者之一是http拦截器。

为了重现该问题,请在StackBlitz上打开http拦截器,并取消注释其中所述的行。在开发者控制台中,您将看到重复的日志消息,这些消息以无限循环的形式出现。 当心:如果等待时间过长,则会导致浏览器标签/窗口崩溃!因此,如果您取消注释后能够再次产生问题,便会再次注释掉这些行!在StackBlitz上,您只需使用STRG + /快捷键即可在多行上切换注释!

非常感谢!

1 个答案:

答案 0 :(得分:2)

我调试了您的代码。

http请求完成后,您将新值推送到用户主题(方法signIn)。您的中断流取决于currentUser$,一旦新用户值到达,中断器就会重新开始。我已修复了中断器以避免此问题,并视当前用户而停止。

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