问题
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