首页 文章

Angular2 Http Interceptor在子模块中不起作用

提问于
浏览
2

所以我创建了一个angular2模块来处理HTTP Intercepting,使用基本的拦截器,如下所示:

@Injectable()
export class RequestInterceptor implements HttpInterceptor {
  constructor(private injector: Injector) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const authService = this.injector.get(AuthService);
    if(authService.isAuthenticated()){
      const authReq = request.clone({
        setHeaders: {
          Authorization: `Bearer ${authService.getAccessToken()}`
        }
      });
      let handle = next.handle(authReq).do(event => {
        if(event instanceof HttpResponse){
          if(event.headers.has('Authorization')){
            authService.updateToken(event.headers.get('Authorization').split(' ')[1]);
          }
        }
      });
      return handle;
    }else{
      return next.handle(request);
    }
  }
}

这将为http请求添加授权标头,并在从服务器发送新标头时更新自己的标头 . 它的导入和提供通常如下:

{
  provide: HTTP_INTERCEPTORS,
  useClass: RequestInterceptor,
  multi: true
},

所以auth angular2模块被编译并导入到我的app.module.t中,效果很好 . 直到我尝试从子模块使用它 . 最佳答案来自:Inherit imports from parent module to child module in Angular2声称angular2不会让你在整个应用程序中全局可用 . 它是否正确?

我通过导入RequestInterceptor从子模块开始工作,并在模块的提供程序中设置它,但我不必这样做,以减少使用它的麻烦 .

2 回答

  • 2

    不是最好的答案 - 但看看这个bug:https://github.com/angular/angular/issues/20575

    特别是评论如下:

    您应该只导入一次HttpClientModule,请参阅docs

    我想你正在模块树的某个地方重新导入 HttpClientModule - 可能在另一个子模块中 . 如果你只是声明它一次,在 AppModule (或者如果它是导入的那个)那么它应该开始在任何地方工作 . 无论如何,这是我的经历 .

    这种恶臭 - 当另一个开发人员稍后在ChildModule中导入bug时,感觉已经成熟,导致错误,并且没有意识到拦截逻辑不再起作用 . 但这似乎是它的方式 .

  • 0

    解决方案是在子模块中导入 HttpClientModule

    imports: [
      ...
      HttpClientModule 
    ],
    declarations: [...],
    providers: [
     { provide: HTTP_INTERCEPTORS, useClass: RequestInterceptor, multi: true }
    ]
    

相关问题