如何在Angular中有条件地添加HttpClient拦截器

时间:2017-08-20 10:58:22

标签: angular angular-http angular-http-interceptors angular-httpclient

最近我一直在使用Angular HttpClient的拦截器。

我添加了与某些HTTP GET方法相对应的标题,对于某些我不需要这些标题。

如何告诉我的拦截器有条件地将拦截器添加到那些方法?我甚至可以拆分服务,例如一个服务用于标题,一个服务没有标题,一个用于不同的标题,一个用于不同的标题。

NgModule提供商

{
  provide: HTTP_INTERCEPTORS,
  useClass: AuthInterceptor,
  multi: true,
},{
  provide: HTTP_INTERCEPTORS,
  useClass: AngularInterceptor,
  multi: true,
}

MyInterceptors

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const authReq = req.clone({headers: req.headers.set('X-Auth-Token', "-------------------------")});
    return next.handle(authReq);

  }
}


@Injectable()
export class AngularInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(req).do(event => {}, err => {
        if(err instanceof HttpErrorResponse){
            console.log("Error Caught By Interceptor");
            //Observable.throw(err);
        }
    });
  }
}

2 个答案:

答案 0 :(得分:1)

注意:我自己还没有尝试过这种方法,但是因为我们正在研究类似的问题,所以我已经尝试了这个方法。

如果我们有非常简单的要求,那么在通用拦截器中添加逻辑并根据URL / Method决定执行哪种拦截是微不足道的。但是,我们的角度应用程序需要调用各种第一方微服务和第三方API,对拦截器有不同的要求。这实际上是您要求的超集。

实现这一点的一个想法是为我们需要调用的每个API /服务扩展HttpClient,并为拦截器链设置自定义注入令牌。您可以看到angular如何注册默认HttpClient here

 providers: [
    HttpClient,
    // HttpHandler is the backend + interceptors and is constructed
    // using the interceptingHandler factory function.
    {
      provide: HttpHandler,
      useFactory: interceptingHandler,
      deps: [HttpBackend, [new Optional(), new Inject(HTTP_INTERCEPTORS)]],
    },

interceptingHandler功能甚至exportedɵinterceptingHandler。我同意这看起来有点奇怪,不知道为什么它有这个出口名称。

Anyawy,要使用自定义的HttpClients,你可以:

export const MY_HTTP_INTERCEPTORS = new InjectionToken<HttpInterceptor[]>('MY_HTTP_INTERCEPTORS');

...
 providers: [
    MyHttpClient,
    {
      provide: MyHttpHandler,
      useFactory: interceptingHandler,
      deps: [HttpBackend, [new Optional(), new Inject(MY_HTTP_INTERCEPTORS)]],
    },

并确保MyHttpClient在其构造函数中需要MyHttpHandler

答案 1 :(得分:1)

我知道现在已经太晚了,我们仍然没有来自 Angular 的任何解决方案。 目前一个简单的解决方法是创建一个 BehaviorSubject 并根据它的值激活拦截器。有了这个,您就可以处理必须使用拦截器的特定 HTTP 请求:

yourService.service.ts

public interceptorTwo = new BehaviorSubject<boolean>(null);

someHttpmethod() {
   this.interceptorTwo.next(true);

   // Add your CODE http
   this.myHttp.post<any>('someUrl', data).finally(() => this.interceptorTwo.next(null));
}

yourInterceptorTwo.service.ts

const setAuth = this.yourService.interceptorTwo.value;
if (!setAuth) {
  return next.handle(req);
}