【问题标题】:Add multiple HTTP Interceptors to Angular Application向 Angular 应用程序添加多个 HTTP 拦截器
【发布时间】:2018-01-19 20:20:28
【问题描述】:

如何向 Angular 4 应用程序添加多个独立的 HTTP 拦截器?

我尝试通过使用多个拦截器扩展 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 类,这应该可以。但是,我想避免这种情况,因为这些拦截器有完全不同的目的(一个用于错误处理,一个用于显示加载指示器)。

那么如何添加多个拦截器呢?

【问题讨论】:

  • 你覆盖了Http。仅使用最后一个覆盖。 Interceptor1 不会被忽略,它只是不存在。您可以使用包含拦截器的 HttpClient。
  • @estus “您可以使用包含拦截器的 HttpClient”是什么意思?
  • 你可以对请求使用不同的拦截器,使用this响应你可以做错误处理,加载器指示器。
  • 这个问题有更新吗?

标签: angular http interceptor angular-http-interceptors


【解决方案1】:

Http 不允许有多个自定义实现。但是正如@estus 提到的,Angular 团队最近添加了一个新的HttpClient 服务(4.3 版),它支持多个拦截器的概念。您不需要像旧的Http 那样扩展HttpClient。您可以为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();
  }
}

【讨论】:

  • 有没有办法告诉api 呼叫只能被一个interceptor 拦截?或任何条件?
  • @k11k2 对于所有搜索的人,这里有一个关于此的问题和答案:stackoverflow.com/questions/45781379/… 我承认我对此仍然有点困惑。
  • 为什么必须是@Injectable()?对我来说,它在没有 @Injectable() 的情况下工作
  • @makkasi:如果拦截器类需要自己进行任何依赖注入,则需要添加@Injectable。在给定的示例中,它不是必需的
  • @AmirReza-Farahlagha 拦截器按提供的顺序调用
猜你喜欢
  • 1970-01-01
  • 2019-05-16
  • 2023-03-13
  • 1970-01-01
  • 2018-07-08
  • 2020-11-08
  • 2017-11-07
  • 2018-05-19
  • 1970-01-01
相关资源
最近更新 更多