向角度应用程序添加多个 HTTP 拦截器

如何将多个独立的 HTTP 拦截器添加到 Angular 4应用程序中?

我试图通过使用多个拦截器扩展 providers数组来添加它们。但是只有最后一个被实际执行,Interceptor1被忽略。

@NgModule({
declarations: [ /* ... */ ],
imports: [ /* ... */ HttpModule ],
providers: [
{
provide: Http,
useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) =>
new Interceptor1(xhrBackend, requestOptions),
deps: [XHRBackend, RequestOptions],
},
{
provide: Http,
useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) =>
new Interceptor2(xhrBackend, requestOptions),
deps: [XHRBackend, RequestOptions]
},
],
bootstrap: [AppComponent]
})
export class AppModule {}

显然,我可以将它们组合成一个单独的 Interceptor类,这应该是可行的。但是,我希望避免这种情况,因为这些拦截器有完全不同的用途(一个用于错误处理,一个用于显示加载指示器)。

那么如何添加多个拦截器呢?

49124 次浏览

Http doesn't allow to have more than one custom implementation. But as @estus mentioned the Angular team has added a new HttpClient service recently (release 4.3) which supports multiple interceptors concept. You don't need to extend the HttpClient as you do with the old Http. You can provide an implementation for HTTP_INTERCEPTORS instead which can be an array with the 'multi: true' option:

import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
...


@NgModule({
...
imports: [
... ,
HttpClientModule
],
providers: [
... ,
{
provide: HTTP_INTERCEPTORS,
useClass: InterceptorOne,
multi: true,
},
{
provide: HTTP_INTERCEPTORS,
useClass: InterceptorTwo,
multi: true,
}
],
...
})

Interceptors:

import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
...


@Injectable()
export class InterceptorOne implements HttpInterceptor {


intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('InterceptorOne is working');
return next.handle(req);
}
}


@Injectable()
export class InterceptorTwo implements HttpInterceptor {


intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('InterceptorTwo is working');
return next.handle(req);
}
}

This server call will print both interceptors' log messages:

import {HttpClient} from '@angular/common/http';
...


@Component({ ... })
export class SomeComponent implements OnInit {


constructor(private http: HttpClient) {}


ngOnInit(): void {
this.http.get('http://some_url').subscribe();
}
}