Is there any way to alter the response in an Angular 5 HttpInterceptor?

我只是一个虾纸丫 提交于 2021-02-07 08:26:19

问题


For my application I have created the following HttpInterceptor. Is there a way to return an altered version of the response to the request subscribers from here?

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']);
                }
            }
        });
    }
}

Thank you.


回答1:


Just like Marcel Lamothe pointed out in his answer, you can alter the response by cloning the event and changing the body property.

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']);
                }
            }
        });
    }
}



回答2:


See the Immutability section of the Http guide: https://angular.io/guide/http#immutability

Interceptors exist to examine and mutate outgoing requests and incoming responses. However, it may be surprising to learn that the HttpRequest and HttpResponse classes are largely immutable.

This is for a reason: because the app may retry requests, the interceptor chain may process an individual request multiple times. If requests were mutable, a retried request would be different than the original request. Immutability ensures the interceptors see the same request for each try.

There is one case where type safety cannot protect you when writing interceptors—the request body. It is invalid to mutate a request body within an interceptor, but this is not checked by the type system.

If you have a need to mutate the request body, you need to copy the request body, mutate the copy, and then use clone() to copy the request and set the new body.

Since requests are immutable, they cannot be modified directly. To mutate them, use clone()



来源:https://stackoverflow.com/questions/47400364/is-there-any-way-to-alter-the-response-in-an-angular-5-httpinterceptor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!