在 Angular 的 HttpInterceptor 中进行实际 http 调用之前调用另一个 http api(没有拦截)
Call another http api (without Intercepting) before actual http call is made in Angular's HttpInterceptor
我正在使用 Angular 的 HttpClientModule
中的 HttpInterceptor
api,但现在遇到了一个问题。这是我的用例。
在我的应用程序中,如果有任何服务进行 http 调用,我想在它之前进行另一个静默 http 调用,并希望将其结果存储在本地。静默调用完成后,只有我会继续服务的 http 调用并 return 结果。
这就是我正在做的。 (使用 HttpInterceptor)
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.url.match(/api\//)) { // api call
http.post('/auth/silentCall', {user: 123}).subscribe(
(data) => {
console.log(data);
const clone = req.clone({ setHeaders: { 'Authorization ': tokenService.getToken() } });
return next.handle(clone).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
console.log('Service's call response');
}
}, (err: any) => {
if (err instanceof HttpErrorResponse) {
console.log('Network call err', err);
}
});
},
(err) => {
if (err instanceof HttpErrorResponse) {
return Observable.throw(err);
}
);
} else {
console.log('Not an api call..It's an auth call');
return next.handle(req); // call original auth request.
}
}
现在,上面代码的问题是,它正在成功执行内部静默调用,但之后再也不会调用原始的 api 调用。所以服务一直在等待。
您没有返回 if
中的 observable
。试试这个
return http.post('/auth/silentCall', {user: 123}).subscribe(
已更新:添加了一个可用的 plunkr。 https://plnkr.co/edit/WFecj8fFZ6z4G6mpLSCr?p=preview
记下调用的顺序以及使用浏览器的开发工具添加的 headers。
另请注意,以下解决方案使用的是 RxJS 可出租运算符而不是标准运算符(这不应该有任何不同的行为...添加此注释以防代码无法编译)
问题的原因在于,在调用匹配 /api
.
的情况下,intercept
方法永远不会 returning 句柄
将您的代码更新为类似于以下内容
intercept(req: HttpRequest<any>, next: HttpHandler):Observable<HttpEvent<any>> {
if (req.url.match(/api\//)) { // api call
return http.post('/auth/silentCall', {user: 123}).pipe(switchMap((response) => {
console.log('Service's call response');
let clone = req.clone({ setHeaders: { 'Authorization ': tokenService.getToken() } });
return next.handle(clone);
}), catchError((err) => {
if(err instanceof HttpErrorResponse) {
console.log('Your logging here...');
let clone = req.clone({ setHeaders: { 'Authorization ': tokenService.getToken() } });
return next.handle(clone);
}
return Observable.throw(err);
}));
} else {
return next.handle(req); // call original auth request.
}
}
请注意,http.post
的响应正在平面映射到 return 由 next.handle()
方法编辑的可观察序列 return 或抛出一个终止的可观察对象 Observable.throw()
.
另请注意,if 条件已被删除,因为如果 api 调用失败,将调用 catch 块(或错误处理函数,在订阅的情况下)
我正在使用 Angular 的 HttpClientModule
中的 HttpInterceptor
api,但现在遇到了一个问题。这是我的用例。
在我的应用程序中,如果有任何服务进行 http 调用,我想在它之前进行另一个静默 http 调用,并希望将其结果存储在本地。静默调用完成后,只有我会继续服务的 http 调用并 return 结果。
这就是我正在做的。 (使用 HttpInterceptor)
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.url.match(/api\//)) { // api call
http.post('/auth/silentCall', {user: 123}).subscribe(
(data) => {
console.log(data);
const clone = req.clone({ setHeaders: { 'Authorization ': tokenService.getToken() } });
return next.handle(clone).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
console.log('Service's call response');
}
}, (err: any) => {
if (err instanceof HttpErrorResponse) {
console.log('Network call err', err);
}
});
},
(err) => {
if (err instanceof HttpErrorResponse) {
return Observable.throw(err);
}
);
} else {
console.log('Not an api call..It's an auth call');
return next.handle(req); // call original auth request.
}
}
现在,上面代码的问题是,它正在成功执行内部静默调用,但之后再也不会调用原始的 api 调用。所以服务一直在等待。
您没有返回 if
中的 observable
。试试这个
return http.post('/auth/silentCall', {user: 123}).subscribe(
已更新:添加了一个可用的 plunkr。 https://plnkr.co/edit/WFecj8fFZ6z4G6mpLSCr?p=preview
记下调用的顺序以及使用浏览器的开发工具添加的 headers。
另请注意,以下解决方案使用的是 RxJS 可出租运算符而不是标准运算符(这不应该有任何不同的行为...添加此注释以防代码无法编译)
问题的原因在于,在调用匹配 /api
.
intercept
方法永远不会 returning 句柄
将您的代码更新为类似于以下内容
intercept(req: HttpRequest<any>, next: HttpHandler):Observable<HttpEvent<any>> {
if (req.url.match(/api\//)) { // api call
return http.post('/auth/silentCall', {user: 123}).pipe(switchMap((response) => {
console.log('Service's call response');
let clone = req.clone({ setHeaders: { 'Authorization ': tokenService.getToken() } });
return next.handle(clone);
}), catchError((err) => {
if(err instanceof HttpErrorResponse) {
console.log('Your logging here...');
let clone = req.clone({ setHeaders: { 'Authorization ': tokenService.getToken() } });
return next.handle(clone);
}
return Observable.throw(err);
}));
} else {
return next.handle(req); // call original auth request.
}
}
请注意,http.post
的响应正在平面映射到 return 由 next.handle()
方法编辑的可观察序列 return 或抛出一个终止的可观察对象 Observable.throw()
.
另请注意,if 条件已被删除,因为如果 api 调用失败,将调用 catch 块(或错误处理函数,在订阅的情况下)