Angular 5的拦截器:发出第二个请求并返回其结果而不是第一个请求的结果

时间:2018-01-16 10:12:46

标签: angular http interceptor angular5

我刚刚将我的Angular应用程序从v4迁移到了v5,我必须重写我的拦截器(通过扩展Http并覆盖request方法)来使用HttpInterceptor接口。

我想要做的是拦截带有201响应代码的请求,使用响应的标头更新请求的标头,执行更新的请求并返回新的响应。

我的代码目前看起来像是:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const handled = next.handle(req);
    return handled.mergeMap(event => {
        // I only work when the response is arrived
        if (event.type === HttpEventType.Response) {
            // The 201 status code tells me I have to update my headers
            if (event.status === 201 && event.url.split('/').pop().toLowerCase() !== 'check') {
                this.authService.updateAuthentication(event.headers.get('new_token')); // update the cookie containing the token
                // I create the updated request
                const requestWithUpdatedHeaders = req.clone({ headers: this.appService.getHeaders() });
                // With this solution, the new request doesn't seem to be performed at all
                return next.handle(requestWithUpdatedHeaders);
                // With this one the request is performed but the result get in my components is null
                return this.http.request(requestWithUpdatedHeaders);               
            } else {
                return handled;
            }
        } else {
            return handled;
        }
    });
}

我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:1)

我终于开始工作了。

我的最终代码是:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next
        .handle(req)
        .mergeMap(event => {
            if (event instanceof HttpResponse && event.status === 201 && event.url.split('/').pop().toLowerCase() !== 'check') {
                if (event.body instanceof Blob) {
                    return this.userService.check()
                        .mergeMap(res => {
                            // update the cookie containing the token
                            this.authService.updateAuthentication(res.headers.get('new_token'));

                            const newReq = req.clone({ headers: this.appService.getHeaders() });
                            return next.handle(newReq);
                        });
                } else {
                    this.authService.updateAuthentication(event.headers.get('new_token'));

                    const newReq = req.clone({ headers: this.appService.getHeaders() });
                    return next.handle(newReq);
                }
            }
            return Observable.of(event);
        });
}

似乎将next.handle(req)存储在变量中并在没有工作要做的情况下将其返回是一个糟糕的主意。

希望我的痛苦至少可以帮助某人:)