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


85

如何将多个独立的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类,并且应该可以工作。但是,我要避免这种情况,因为这些拦截器的用途完全不同(一个用于错误处理,一个用于显示加载指示符)。

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


2
你压倒一切Http。仅使用最后一个替代。Interceptor1不会被忽略,只是不存在。您可以使用包含拦截器的HttpClient。
Estus Flask,

@estus“您可以使用包含拦截器的HttpClient”是什么意思?
str


您可以对请求使用不同的拦截器,并使用来执行错误处理,加载程序指示符。
nivas

这个问题有什么更新吗?
Renil Babu

Answers:


162

Http不允许有多个自定义实现。但是正如@estus所述,Angular团队最近添加了新的HttpClient服务(版本4.3),该服务支持多个拦截器概念。您无需HttpClient像使用旧版那样扩展Http。您可以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();
  }
}

4
有什么办法可以告诉api电话只能被一个人拦截interceptor吗?或在任何条件下?
k11k2

@ k11k2,对于所有正在搜索的人,这是一个关于此的问答:stackoverflow.com/questions/45781379/…我承认我对此仍然有些困惑。
trollkotze

为什么必须是@Injectable()?它对我来说没有@Injectable()就可以工作
makkasi '18

1
@makkasi:如果拦截器类需要自己进行任何依赖项注入,则需要添加@Injectable。在给定的示例中,它不是必需的
jintoppy

如何解决拦截器订购问题?
AmirReza-Farahlagha
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.