Dodaj wiele Interceptorów HTTP do aplikacji Angular

85

Jak dodać wiele niezależnych przechwytywaczy HTTP do aplikacji Angular 4?

Próbowałem je dodać, rozszerzając providerstablicę o więcej niż jeden przechwytywacz. Ale tylko ostatnia jest faktycznie wykonywana, Interceptor1jest ignorowana.

@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 {}

Mógłbym oczywiście połączyć je w jedną Interceptorklasę i to powinno działać. Chciałbym jednak tego uniknąć, ponieważ te przechwytywacze mają zupełnie inne cele (jeden do obsługi błędów, drugi do wyświetlania wskaźnika ładowania).

Jak więc mogę dodać wiele przechwytywaczy?

str
źródło
2
Jesteś nadrzędny Http. Używana jest tylko ostatnia zmiana. Interceptor1 nie jest ignorowany, po prostu nie istnieje. Możesz użyć HttpClient, który zawiera przechwytywacze.
Estus Flask,
@estus Co masz na myśli, mówiąc „Możesz użyć HttpClient, który zawiera przechwytywacze”?
str.
angular.io/guide/http
Estus Flask
możesz użyć różnych przechwytywaczy dla żądania, odpowiedzi używając tego , możesz zrobić obsługę błędów, wskaźnik modułu ładującego.
nivas
Czy jest jakaś aktualizacja na to pytanie?
Renil Babu

Odpowiedzi:

162

Httpnie pozwala na więcej niż jedną niestandardową implementację. Ale jak wspomniał @estus, zespół Angular dodał niedawno nową usługę HttpClient (wersja 4.3), która obsługuje koncepcję wielu przechwytywaczy. Nie musisz przedłużać, tak HttpClientjak w przypadku starego Http. Zamiast tego możesz podać implementację, HTTP_INTERCEPTORSktóra może być tablicą z 'multi: true'opcją:

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

Interceptory:

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

To wywołanie serwera wydrukuje komunikaty dziennika obu przechwytywaczy:

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();
  }
}
hiper2d
źródło
4
Czy istnieje sposób, aby stwierdzić, że apipołączenie może zostać przechwycone tylko przez jednego interceptor? czy pod jakimikolwiek warunkami?
k11k2
@ k11k2 i dla wszystkich szukających, oto pytanie i odpowiedź na ten temat: stackoverflow.com/questions/45781379/… Przyznaję, że nadal jestem trochę zdezorientowany.
trollkotze
Dlaczego musi być @Injectable ()? Działa bez @Injectable () dla mnie
makkasi
1
@makkasi: należy dodać @ Injectable, jeśli klasa przechwytująca musi samodzielnie wykonać wstrzyknięcie zależności. W podanym przykładzie nie jest to wymagane
jintoppy
Jak naprawić zamawianie przechwytywaczy?
AmirReza-Farahlagha