Добавление нескольких HTTP-перехватчиков в приложение Angular

Как добавить несколько независимых 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, и это должно сработать. Однако я хотел бы избежать этого, поскольку эти перехватчики имеют совершенно разные цели (один для обработки ошибок, один для показа индикатора загрузки).

Итак, как я могу добавить несколько перехватчиков?

Ответы

Ответ 1

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