1. ホーム
  2. angular

[解決済み] Angularアプリケーションに複数のHTTPインターセプターを追加する

2023-01-22 22:06:39

質問

Angular 4 アプリケーションに複数の独立した HTTP インターセプターを追加するにはどうしたらよいでしょうか。

を拡張して追加しようとしたのですが providers 配列に複数のインターセプターを追加してみました。しかし、実際に実行されるのは最後の1つだけです。 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つはエラー処理のため、1つはロードインジケータを表示するため)を持っているので、私はそれを避けたいと考えています。

では、どうすれば複数のインターセプターを追加できるのでしょうか?

どのように解決するのでしょうか?

Http は複数のカスタム実装を持つことを許可していません。しかし、@estus が言及したように、Angular チームは新しい HttpClient サービスが追加され、複数のインターセプターのコンセプトがサポートされました。を拡張する必要はありません。 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();
  }
}