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

Posted

技术标签:

【中文标题】向 Angular 应用程序添加多个 HTTP 拦截器【英文标题】:Add multiple HTTP Interceptors to Angular Application 【发布时间】:2018-01-19 20:20:28 【问题描述】:

如何向 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。仅使用最后一个覆盖。 Interceptor1 不会被忽略,它只是不存在。您可以使用包含拦截器的 HttpClient。 @estus “您可以使用包含拦截器的 HttpClient”是什么意思? angular.io/guide/http 你可以对请求使用不同的拦截器,使用this响应你可以做错误处理,加载器指示器。 这个问题有更新吗? 【参考方案1】:

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

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

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

【讨论】:

有没有办法告诉api 呼叫只能被一个interceptor 拦截?或任何条件? @k11k2 对于所有搜索的人,这里有一个关于此的问题和答案:***.com/questions/45781379/… 我承认我对此仍然有点困惑。 为什么必须是@Injectable()?对我来说,它在没有 @Injectable() 的情况下工作 @makkasi:如果拦截器类需要自己进行任何依赖注入,则需要添加@Injectable。在给定的示例中,它不是必需的 @AmirReza-Farahlagha 拦截器按提供的顺序调用

以上是关于向 Angular 应用程序添加多个 HTTP 拦截器的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2/4 如何将多个标题添加到 http post

如何在 Angular 5 HttpInterceptor 中添加多个标头

在Angular 11中添加多个同名参数

不记名令牌未添加到 HTTP 请求 - MSAL2 Angular

如何使用 DaoAuthenticationProvider 向 Spring 应用程序添加一个 REST Angular 自定义登录页面

我们可以在 AOT 之后向 Angular 应用程序添加功能模块吗