13

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

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

如何告诉我的拦截器有条件地将拦截器添加到这些方法?我什至可以拆分服务,例如一项服务用于标头,一项服务没有标头,或者一项用于不同标头,一项用于不同标头。

NgModule 提供者

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

我的拦截器

@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);
        }
    });
  }
}
4

2 回答 2

2

我知道为时已晚,但是我们仍然没有来自 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);
}
于 2020-12-31T12:10:27.263 回答
1

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

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

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

 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函数甚至导出ɵinterceptingHandler. 我同意这看起来有点奇怪,不知道为什么它有那个出口名称。

无论如何,要使用自定义 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需要 a 。MyHttpHandler

于 2017-09-28T09:01:11.570 回答