Angular HttpInterceptor无法为响应添加Correlation-Id头如何解决?
问题原因与解决方案
1. 核心原因:拦截器修改的是Angular内部响应对象,不会更改浏览器原生网络请求的响应头
Angular的HttpInterceptor是HttpClient封装层的中间件,你对HttpResponse的clone修改仅作用于Angular内部传递给业务代码的响应实例,不会修改浏览器层面真实的HTTP响应数据。
所以你在浏览器开发者工具的「网络」标签里看到的响应头还是后端原始返回的结果,不会显示你新增的Correlation-Id。你可以在业务代码中订阅请求后,调用response.headers.get('Correlation-Id')验证,已经可以正常拿到你设置的值。
如果需要在浏览器网络面板也能看到这个响应头,需要后端服务在返回响应时主动把请求携带的Correlation-Id添加到响应头中,前端拦截器无法修改原生网络请求的响应数据。
2. 现有拦截器的隐藏问题:事件丢失
你当前的代码使用filter操作符只放行HttpResponse类型的事件,其他所有Http事件(比如请求发送事件、上传/下载进度事件等)都会被过滤丢弃,会导致依赖这些事件的功能(比如文件上传进度监听)异常。
你可以按如下方式修改拦截器逻辑:
import * as uuid from 'uuid'; import { HttpEvent, HttpHandler, HttpHeaders, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @Injectable() export class RequestTracker implements HttpInterceptor { intercept( httpRequest: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> { const correlationId = uuid.v4(); const httpRequestClone = httpRequest.clone({ setHeaders: { 'Correlation-Id': correlationId } }); return next.handle(httpRequestClone).pipe( map((event: HttpEvent<any>) => { // 仅修改响应事件,其他事件直接返回 if (event instanceof HttpResponse) { return event.clone({ headers: event.headers.set('Correlation-Id', correlationId) }); } return event; }) ); } }
内容的提问来源于stack exchange,提问作者Ankit Tanna
相关产品推荐
相关产品推荐

