4

对于我的应用程序,我创建了以下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']);
                }
            }
        });
    }
}

谢谢你。

4

2 回答 2

17

就像 Marcel Lamothe 在他的回答中指出的那样,您可以通过克隆事件和更改 body 属性来更改响应。

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']);
                }
            }
        });
    }
}
于 2017-11-21T11:30:34.590 回答
3

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

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

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

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

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

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

于 2017-11-20T20:42:02.590 回答