Angular 从入坑到挖坑 - HTTP 请求概览 (5)

因为会存在定义多个拦截器的情况,所以这里需要指定 multi 属性为 true

import { HTTP_INTERCEPTORS } from '@angular/common/http'; // 需要添加的拦截器 import { LoggingInterceptor } from './logging-interceptor'; // 返回的拦截器数组 export const HttpInterceptorProviders = [ { provide: HTTP_INTERCEPTORS, useClass: LoggingInterceptor, multi: true } ];

由于拦截器具有将发送到服务端的 HTTP 请求进行监视、转化,以及拦截请求的响应信息的双重效果,因此当我们注册了多个拦截器时,在发送请求时会按照我们添加的顺序进行执行,而在接受到请求响应时,则是按照反过来的顺序进行执行

获取到导出的拦截器信息,就可以在根模块中去导入需要注册的拦截器

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; // 添加自定义拦截器 import { HttpInterceptorProviders } from './http-interceptors/http-interceptor-providers'; @NgModule({ declarations: [ AppComponent, AntiMotivationalQuotesComponent ], imports: [ BrowserModule, AppRoutingModule, FormsModule, HttpClientModule // 添加到根应用模块中 ], providers: [ HttpInterceptorProviders ], bootstrap: [AppComponent] }) export class AppModule { }

添加拦截器

4.3.2、修改请求信息

由于一个请求可能会存在重试发起的情况,为了确保多次发起请求时的请求信息的不变性,对于 HttpRequest 和 HttpResponse 我们是不可以修改原始的对象属性值的

当我们需要对请求进行修改时,例如在请求的 header 中添加上 token 信息,此时我们需要先克隆一个原始的请求对象,在这个克隆后的请求上进行操作,最终将这个克隆后的请求传递给下一个拦截器

import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/internal/Observable'; import { Injectable } from '@angular/core'; import { tap, finalize } from 'rxjs/operators'; /** * 通过添加 Injectable 特性,表明可以通过依赖注入的方式进行创建 */ @Injectable() export class LoggingInterceptor implements HttpInterceptor { /** * 请求拦截 * @param req http 请求 * @param next 下一个拦截器 */ intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // 开始时间 const started = Date.now(); let msg: string; // 打印原始的请求信息 console.log(`原始的请求信息:${JSON.stringify(req.headers)}`); // 获取请求中的 token 信息 const token = req.headers.get('Authorization') || ''; // 克隆请求信息 const authReq = req.clone({ headers: token === '' ? req.headers.set('Authorization', '123456') : req.headers }); // 打印修改后的请求信息 console.log(`克隆后的请求信息:${JSON.stringify(authReq.headers)}`); // 将克隆后的 http 请求信息传递给下一个拦截器 return next.handle(authReq) .pipe( tap( // 捕获当前请求是否成功 or 失败 // 1、通过判断响应的类型是否为 HttpResponse 来判断请求是否成功 event => msg = event instanceof HttpResponse ? '请求成功' : '请求失败', // 2、如果存在了 error 回调,则请求失败 error => msg = '请求失败' ), finalize(() => { const elapsed = Date.now() - started; console.log(`请求方式:${req.method} 请求地址:${req.urlWithParams} 响应耗时:${elapsed} ms 请求结果:${msg}`); })); } }

克隆请求信息

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspsjf.html