Додайте кілька перехоплювачів HTTP до Angular Application


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. Використовується лише останнє скасування. Перехоплювач1 не ігнорується, він просто не існує. Ви можете використовувати HttpClient, який містить перехоплювачі.
Estus Flask

@estus Що ви маєте на увазі під "Ви можете використовувати HttpClient, який має перехоплювачі."?
вул.


ви можете використовувати різні перехоплювачі для запиту, відповідь використовуючи це, що ви можете обробляти помилки, індикатор завантажувача.
nivas

Чи є оновлення щодо цього питання?
Реніл Бабу,

Відповіді:


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/… Я визнаю, що я все ще трохи збентежений з цього приводу.
тролкотце

Чому має бути @Injectable ()? Для мене це працює без @Injectable ()
makkasi

1
@makkasi: Потрібно додати @ Injectable, якщо класу перехоплювачів потрібно зробити будь-яку власну ін'єкцію залежностей. У наведеному прикладі це не потрібно
jintoppy

Як виправити замовлення перехоплювачів?
AmirReza-Farahlagha
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.