TL:DR 答案:
不,没有办法。拦截器旨在拦截all要求。
长答案:
存储库和请求都不应该知道它可以传递的拦截器。因此,我不同意标记请求或检查特定类的解决方案。
我更喜欢这里提供的解决方案:Angular HttpInterceptor 示例 https://offering.solutions/blog/articles/2017/07/19/angular-2-new-http-interface-with-interceptors/
基本上,您的拦截器必须检查服务(中介模式)是否应添加特定标头。
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log(JSON.stringify(req));
const token: string = this.currentUserService.token;
if (token) {
req = req.clone({ headers: req.headers.set('Authorization', 'Bearer ' + token) });
}
if (!req.headers.has('Content-Type')) {
req = req.clone({ headers: req.headers.set('Content-Type', 'application/json') });
}
req = req.clone({ headers: req.headers.set('Accept', 'application/json') });
return next.handle(req);
}
这是一个很好的例子,但请注意它违反了单一职责原则(设置多个标头)。
除此之外,我的观点是,拦截器对于您的问题来说是错误的模式。另外,我没有看到拦截器作为向请求添加不记名令牌的解决方案。这就是我的用例将我带到这里。
基本上我会挑战你的架构并重新思考你如何创建请求。该问题的解决方案可以采用以下设计:
摘要存储库
具有 get / post / put 等基本方法,返回 HttpRequest。
有一个名为“send”的方法,它接受 HttpRequest 作为参数。
具体存储库
继承抽象存储库,扩展基本请求功能。
因此,对于您的用例,您有一个基本服务,并且每个特定/自定义服务都继承自该特定服务,该服务扩展了您的请求的行为。
装饰者
为了使这个架构更进一步(就像我所做的那样),您可以创建一个打字稿装饰器(并非在所有情况下都可行,例如,当需要依赖注入时),它扩展了所有装饰函数的行为。例如添加特定的标头。这可能看起来像这样:
import { Observable } from 'rxjs/Observable';
import { HttpClient, HttpRequest, HttpEvent } from '@angular/common/http';
import { Injectable } from '@angular/core';
export abstract class BaseRepository<T> {
constructor(protected client: HttpClient) {
}
public createGetRequest(url: string): HttpRequest<T> {
return new HttpRequest("GET", url);
}
public send(request: HttpRequest<T>): Observable<HttpEvent<T>> {
return this.client.request(request);
}
}
@Injectable()
export class NormalServiceRepository extends BaseRepository<any> {
constructor(protected client: HttpClient) {
super(client);
}
public get(url: string): Observable<any> {
const baseRequest = super.createGetRequest(url);
baseRequest.headers.set('Content-Type', 'application/json');
return this.send(baseRequest);
}
}
@Injectable()
export class AuthServiceRepository extends BaseRepository<any> {
constructor(protected client: HttpClient) {
super(client);
}
@AcceptsJson()
@SendsJson()
@ForwardCredentials()
public createGetRequest(url: string): HttpRequest<any> {
return super.createGetRequest(url);
}
public get(url: string): Observable<any> {
const baseRequest = super.createGetRequest(url);
return this.send(baseRequest);
}
}
这应该能让您对架构的外观有一个基本的了解。
关于装饰器的更多信息
TypeScript 装饰器 http://www.typescriptlang.org/docs/handbook/decorators.html
示例实现 https://gist.github.com/remojansen/16c661a7afd68e22ac6e