【问题标题】:Is there any way to alter the response in an Angular 5 HttpInterceptor?有没有办法改变 Angular 5 HttpInterceptor 中的响应?
【发布时间】:2018-05-04 03:57:44
【问题描述】:

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

谢谢。

【问题讨论】:

    标签: angular typescript rxjs angular-httpclient


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-26
        • 2020-06-09
        • 1970-01-01
        • 1970-01-01
        • 2019-06-21
        • 1970-01-01
        相关资源
        最近更新 更多