在发送请求之前,我需要根据我的最初意图在Angular的HTTP拦截器中有条件地采取行动。这是一个简单的抽象构成:
HttpClient 发出的请求完全相同(URL,参数等),有两个目的:
需要显示加载程序的请求(例如页面更改,初始加载等)
this.http.post(url, data, config = {**someCustomParam**: true});
请求不显示的内容(例如状态检查,ping等)
this.http.post(url, data, config = {**someCustomParam**: false});
拦截请求的结果是这样的:
@Injectable()
export class RequestInterceptor implements HttpInterceptor {
constructor(private injector: Injector) { }
public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).do((event: HttpEvent<any>) => {
if (event instanceof HttpErrorResponse) {
}
}, (err: any) => {
if(request.someCustomProperty) {
**// Do somethnig on TRUE**
} else {
**// Do somethnig on FALSE**
}
});
}
}
我面临的问题是我无法在请求中传递自定义参数,并且无法在响应到达后再见面。到目前为止,这是我发现的内容:
提前谢谢!
答案 0 :(得分:1)
我认为最正确的方法是注入服务,该服务应负责通过在服务中使用吸气剂来决定是否做某事。
在此示例中,是否修改请求并添加Authorization
标头的决定基于注入的isAuthenticated
的getter AuthService
的值:
export class AuthInterceptorService implements HttpInterceptor {
constructor(private authService: AuthService) {}
intercept(req: HttpRequest<any>, next: HttpHandler) : Observable<HttpEvent<any>> {
if (this.authService.isAuthenticated) {
const authorizationHeader = this.authService.authorizationHeaderValue;
const modifiedReq = req.clone({
headers: new HttpHeaders().set('Authorization', authorizationHeader)
});
return next.handle(modifiedReq);
}
else {
return next.handle(req);
}
}
}
这是AuthService
:
export class AuthService {
private user: User | null;
get isAuthenticated(): boolean {
return this.user != null && !this.user.expired;
}
get authorizationHeaderValue(): string {
if (this.user)
return `${this.user.token_type} ${this.user.access_token}`;
else
return '';
}
}
答案 1 :(得分:0)
不建议使用前两种方法。
最终方法: 我建议您采用第三种方法。
您应该创建一个装饰器,该装饰器仅在需要显示加载程序时才使用。这样,其他任何人都将更容易理解。而且逻辑不会依赖于后端。
答案 2 :(得分:0)
我建议您将自定义参数作为标头添加到请求中,无论如何您都可以在拦截器中检查它并从请求中删除它。这将是最快的解决方案。
...或...
我在我的一个项目中使用@LoaderTrigger装饰器来启动加载器,但没有使用拦截器。您只需要装饰一个返回可观察的方法或函数并实现LoaderManager。所以这是它的样子:
function LoaderTrigger(target, key, descriptor) {
if (descriptor === undefined) {
descriptor = Object.getOwnPropertyDescriptor(target, key);
}
const originalMethod = descriptor.value;
descriptor.value = function () {
LoaderManager.onStarted();
return originalMethod.apply(this, arguments)
.map((value) => {
LoaderManager.onLoaded();
return value;
})
.catch((err) => {
LoaderManager.onLoaded();
return Observable.throw(err);
});
};
return descriptor;
}
答案 3 :(得分:0)
作为一种解决方法,我编写了一个在执行http请求之前起作用的代码。
在加载组件的服务上,我添加了防止下一个启动顺序的功能:
ignoreNextOrder(){
this.ignore = true;
}
start() {
if (this.ignore){
this.ignore = false;
return
}
this.loadingSubject.next(LoadingType.LOADING);
}
您必须在不想显示加载动画的请求之前手动调用它,以便在进行http调用并且拦截器尝试启动加载动画时,它将被忽略。