HttpRequest被拦截时被取消

时间:2019-03-30 12:01:19

标签: typescript angular7 angular-httpclient angular-http-interceptors api-gateway

问题

我正在使用HttpInterceptor向所有HTTP请求添加Authorize标头。这些请求将发送到AWS API Gateway。但是不幸的是,如果我拦截了所有请求,这些请求将被取消。

如果我将标头直接添加到请求中,那么一切都会按预期工作,但是由于异步获取了我的令牌,因此第一个请求将失败,因为该令牌尚不可用。这就是为什么我添加如下所示的拦截器的原因,其中this.getSession()从Promise返回一个Observable:

intercept (request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {       
        return this.getSession()
            .mergeMap((session: CognitoUserSession) => {   
                if(session.getIdToken()){
                    request = request.clone({
                        setHeaders: {
                            Authorization: session.getIdToken().getJwtToken()
                        }
                    });  
                }
                return next.handle(request);
         });
    }

请求本身如下执行:

getStoreList(): Observable<string[]> {
 let uri = endpoint + 'getStores';
 return this.http.get<string[]>(uri, {headers: httpHeaders}).pipe(
   map((data) => {
     return data;
 }));
}

this.updateHistoryService.getStoreList()
      .subscribe((data: string[]) => {
        this.stores = ["all", ...data];
        this.getData();
});

但这导致: “ XHR加载失败:选项“ https://....eu-central-1.amazonaws.com/dev/getStores”” (我正在使用CORS,这就是发送飞行前请求的原因。)

我尝试过的

如果我更改此行:

return next.handle(request);

收件人:

return from(next.handle(request).toPromise());

//the following works as well:
return next.handle(request).toPromise();

我可以在控制台中看到,已成功从服务器加载了数据,而没有取消任何请求,但是从未以这种方式调用我的回调,所以我无法处理数据。

1 个答案:

答案 0 :(得分:0)

我通过添加.pipe(takeWhile(() => this.alive))使它正常工作。 看起来像这样:

return this.getSession()
   .pipe(takeWhile(() => this.alive))
        .mergeMap((session: CognitoUserSession) => {   
            if(session.getIdToken()){
                request = request.clone({
                    setHeaders: {
                        Authorization: session.getIdToken().getJwtToken()
                    }
                });  
            }
            return next.handle(request);
     });