有没有办法改变Angular 5 HttpInterceptor中的响应?

时间:2017-11-20 20:20:23

标签: angular typescript rxjs angular-httpclient

对于我的应用程序,我创建了以下HttpInterceptor。有没有办法从这里向请求订阅者返回更改的响应版本?

import { Injectable } from '@angular/core';
import { HttpRequest, HttpResponse, HttpErrorResponse, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Router } from '@angular/router';

@Injectable()
export class RequestInterceptor implements HttpInterceptor {
    constructor(
        private router: Router
    ) { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).do((event: HttpEvent<any>) => {
            if (event instanceof HttpResponse) {
                // any way to alter response that gets sent to the request subscriber?
            }
        }, (error: any) => {    
            if (error instanceof HttpErrorResponse) {
                if (error.status === 401 || error.status === 403) {
                    console.log('The authentication session has expired or the user is not authorised. Redirecting to login page.');
                    this.router.navigate(['/login']);
                }
            }
        });
    }
}

谢谢。

2 个答案:

答案 0 :(得分:10)

就像Marcel Lamothe在答案中指出的那样,你可以通过克隆事件和改变身体属性来改变反应。

import { Injectable } from '@angular/core';
import { HttpRequest, HttpResponse, HttpErrorResponse, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Router } from '@angular/router';

@Injectable()
export class RequestInterceptor implements HttpInterceptor {
    constructor(
        private router: Router
    ) {}

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).map((event: HttpEvent<any>) => {
            if (event instanceof HttpResponse) {
                // change the response body here
                return event.clone({
                    body: 'myCustomResponse'
                });
            }

            return event;
        }).do((event: HttpEvent<any>) => {}, (error: any) => {
            if (error instanceof HttpErrorResponse) {
                if (error.status === 401 || error.status === 403) {
                    console.log('The authentication session has expired or the user is not authorised. Redirecting to login page.');
                    this.router.navigate(['/login']);
                }
            }
        });
    }
}

答案 1 :(得分:3)

请参阅Http指南的Immutability部分: https://angular.io/guide/http#immutability

  

存在拦截器来检查和改变传出请求和传入响应。但是,了解HttpRequest和HttpResponse类在很大程度上是不可变的可能会令人惊讶。

     

这是有原因的:因为app可能会重试请求,拦截器链可能会多次处理单个请求。如果请求是可变的,则重试的请求将与原始请求不同。不可变性确保拦截器每次尝试都能看到相同的请求。

     

在编写拦截器 - 请求体时,有一种情况是类型安全无法保护您。在拦截器中改变请求体是无效的,但类型系统不会检查它。

     

如果您需要改变请求正文,则需要复制请求正文,改变副本,然后使用clone()复制请求并设置新正文。

     

由于请求是不可变的,因此无法直接修改它们。要改变它们,请使用clone()