【问题标题】:Angular ngrx infinite loop with interceptors带有拦截器的 Angular ngrx 无限循环
【发布时间】:2019-11-28 02:58:44
【问题描述】:

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

拦截(请求:HttpRequest,下一个:HttpHandler):Observable> { 返回 this.store.select(SessionSelectors.sessionToken).pipe( 第一的(), 合并映射(令牌 => { console.log("拦截器 1"); 如果(令牌){ request = request.clone({ headers: request.headers.set('Authorization', 'User' + token) }); } 返回下一个。句柄(请求); }) ); } 拦截(请求:HttpRequest,下一个:HttpHandler):Observable> { return next.handle(request).pipe(map((event: HttpEvent) => { 如果(事件实例的 HttpResponse){ console.log("拦截器 2"); if (event.headers.has("X-Session-Expiration")) { var value = event.headers.get("X-Session-Expiration"); var过期=新日期(值); this.store.dispatch(new SessionActions.RefreshSessionExpiration({ newExpirationDate: expire })); } 返回事件; })); }

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

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

【问题讨论】:

  • 您是否尝试过在您的第一个拦截器中使用switchMap 而不是mergeMap
  • 感谢您的回答,是的,我尝试了 switchMap、mergeMap 和 flatMap。没有变化

标签: angular ngrx ngrx-store


【解决方案1】:

尝试在拦截器的开头添加 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);
  })
 );
}

【讨论】:

    猜你喜欢
    • 2015-08-16
    • 2017-10-17
    • 1970-01-01
    • 2019-06-14
    • 2020-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多