Angularアプリケーションに複数のHTTPインターセプターを追加する


86

複数の独立したHTTPインターセプターをAngular4アプリケーションに追加するにはどうすればよいですか?

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つは負荷インジケーターを表示するため)、これは避けたいと思います。

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


2
オーバーライドしていますHttp。最後のオーバーライドのみが使用されます。Interceptor1は無視されず、存在しないだけです。インターセプターが含まれているHttpClientを使用できます。
Estus Flask 2017

@estus「インターセプターが含まれているHttpClientを使用できる」とはどういう意味ですか?
str 2017


要求、これを使用した応答にさまざまなインターセプターを使用て、エラー処理、ローダーインジケーターを実行できます。
nivas 2017

この質問に関する更新はありますか?
RenilBabu19年

回答:


164

Http複数のカスタム実装を持つことはできません。しかし、@ estusが述べたように、Angularチームは最近(リリース4.3)、複数のインターセプターの概念をサポートする新しいHttpClientサービスを追加しました。HttpClient古いもののようにを拡張する必要はありませんHttpHTTP_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通話を1人だけで傍受できることを伝える方法はありますinterceptorか?または任意の条件によって?
k11k2 2018年

@ k11k2そして検索しているすべての人のために、これについての質問と回答があります:stackoverflow.com/questions/45781379/…私はまだそれについて少し混乱していることを認めます。
trollkotze 2018年

なぜ@Injectable()でなければならないのですか?@Injectable()がなくても機能します
makkasi 2018

1
@makkasi:インターセプタークラスが独自の依存性注入を行う必要がある場合は、add @Injectableが必要です。与えられた例では、それは必須ではありません
jintoppy 2018

1
@ AmirReza-Farahlaghaインタセプタは、それらが設けられた順番で呼び出されます
hiper2d
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.