所以我创建了一个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从子模块开始工作,并在模块的提供程序中进行设置,但我不必这样做,以减少使用它的麻烦。
答案 0 :(得分:6)
不是最佳答案 - 但请查看此错误:https://github.com/angular/angular/issues/20575
特别是评论:
您应该只导入一次HttpClientModule,请参阅docs
我想你正在模块树的某个地方重新导入HttpClientModule
- 可能在另一个子模块中。如果您只是在AppModule
(或者如果它是导入的那个)中声明它一次,那么它应该在任何地方开始工作。无论如何,那是我的经历。
这种恶臭 - 当另一个开发人员稍后在ChildModule中导入错误时,感觉已经成熟,导致错误,并且没有意识到拦截逻辑不再起作用。但这似乎是它的方式。
答案 1 :(得分:0)
我遇到了类似的问题。我有一个自定义的HTTP拦截器,目的是将JWT发送到API,并且奇怪的是,在我的某些组件正常工作时,其中一些组件只是被401服务器拒绝了。在我的应用程序中导入了HttpClientModules。我清除了所有内容,仅在AppModule(根)中导入了HttpClientModule。之后,一切都固定了。
答案 2 :(得分:0)
我有同样的问题。拦截器未添加在延迟加载的模块中发出的令牌请求。除非您要覆盖HttpClientModule实例,否则导入HttpClientModule并不是最佳选择。如果再次导入HttpClientModule,它将覆盖根模块中声明的所有拦截器。
角度文档的直接报价:
要在整个应用程序中使用相同的HttpInterceptors实例,请仅在AppModule中导入HttpClientModule,然后将拦截器添加到根应用程序注入器中。如果跨不同模块(例如,在延迟加载模块中)多次导入HttpClientModule,则每次导入都会创建HttpClientModule的新副本,该副本将覆盖根模块中提供的拦截器。
https://angular.io/api/common/http/HttpInterceptor#usage-notes
答案 3 :(得分:-2)
解决方案是也在子模块中导入 HttpClientModule
imports: [
...
HttpClientModule
],
declarations: [...],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: RequestInterceptor, multi: true }
]