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

我试图通过使用多个拦截器扩展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个班,这应该行得通.然而,我想避免这种情况,因为这些拦截器有完全不同的用途(一个用于错误处理,一个用于显示加载指示器).

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

推荐答案

Http不允许有多个自定义实现.但是正如@estus提到的,Angular团队最近增加了一个新的HttpClient服务(4.3版),它支持多个拦截器的概念.你不需要像旧的Http那样扩展HttpClient.您可以为HTTP_INTERCEPTORS提供一个实现,它可以是一个带有'multi: true'选项的数组:

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,
    }
  ],
  ...
})

拦截器:

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);
  }
}

此服务器调用将打印两个拦截器的日志(log)消息:

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();
  }
}

Angular相关问答推荐

Angular 信号效果,try 重置表单并获取在计算或效果中不允许写入信号"

嵌套formArrays的HTML迭代

基于另一个控制值显示值的Angular 数组

类是一个独立的组件,不能在Angular中的`@NgModule.bootstrap`数组中使用

Angular 16独立依赖注入问题

如何正确导出/导入枚举和接口文件以便 Jest 成功完成测试?

错误:在@angular/core中找不到导出ɵivyEnabled(导入为ɵivyEnabled)

Angular:try 在点击次数后禁用按钮

将数组传递给 URLSearchParams,同时使用 http 调用获取请求

带有重定向的Angular 2 AuthGuard服务?

如何设置Angular 4背景图片?

如何在 Angular4 中访问组件的 nativeElement?

如何使用Angular4通过元素ID设置焦点

在同一个组件中使用 MatSort 的多个 mat-table

Angular Material 模态对话框周围的空白

Angular 2 Material - 如何居中进度微调器

Angular为 4 的可扩展表格行,带有Angularmaterial

使用 DomSanitizer 绕过安全性后,安全值必须使用 [property]=binding

angular 5 material - 表单字段停留在 180px

如何在 Angular 2 中链接 HTTP 调用?