带有拦截器的Angular Ngrx无限循环

时间:2019-07-19 06:47:29

标签: angular ngrx ngrx-store

我使用ngrx来存储我的会话信息(令牌本身及其有效期)。 http管道中有两个拦截器:拦截器1将存储中的令牌注入到http请求中,拦截器2从响应中读取一个自定义的HTTP标头“ X-Session-Expiration”,并将其放置在存储中(我也有两个在一个拦截器中执行操作,也不能解决问题)。

intercept(request: HttpRequest, next: HttpHandler): Observable> {

    return this.store.select(SessionSelectors.sessionToken).pipe(
      first(),
      mergeMap(token => {
        console.log("interceptor 1");

        if (token) {
          request = request.clone({ headers: request.headers.set('Authorization', 'User ' + token) });
        }

        return next.handle(request);
      })
    );
}
intercept(request: HttpRequest, next: HttpHandler):  Observable> {

    return next.handle(request).pipe(map((event: HttpEvent) => {
      if (event instanceof HttpResponse) {
        console.log("interceptor 2");

        if (event.headers.has("X-Session-Expiration")) {
          var value = event.headers.get("X-Session-Expiration");
          var expiration = new Date(value);

          this.store.dispatch(new SessionActions.RefreshSessionExpiration({ newExpirationDate: expiration }));
      }

      return event;
    }));
}

这将创建一个无限循环。拦截器2中的store修改会触发拦截器1中的订阅,从而触发http请求,从而触发拦截器2,依此类推。

为防止这种情况,我在拦截器1中插入了first()或take(1),但似乎没有任何改变。

1 个答案:

答案 0 :(得分:0)

尝试在拦截器的开头添加 if 语句

intercept(request: HttpRequest, next: HttpHandler): Observable> {
if (request.url === 'api/refresh-token') {
    return next.handle(request);
}

 return this.store.select(SessionSelectors.sessionToken).pipe(
    mergeMap(token => {
      .....
    }

    return next.handle(requestWithToken);
  })
 );
}