如何通过Angular拦截器从响应头取值设置到全局请求头
实现步骤
1. 后端先配置响应头暴露(必做)
跨域场景下浏览器默认会隐藏自定义响应头,前端无法直接读取,需要SpringBoot端额外配置允许前端访问HeaderName头,二选一配置即可:
- 如果你用
CorsRegistry做跨域配置,追加一行:
corsConfiguration.addExposedHeader("HeaderName");
- 直接在返回响应时加暴露头:
response.getHeaders().add("Access-Control-Expose-Headers", "HeaderName");
2. 前端创建公共存储(可选,也可直接用sessionStorage)
创建单例服务存储头值,避免全局变量污染,示例header-storage.service.ts:
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class HeaderStorageService { // 不需要刷新后仍保留值的话,可以直接把sessionStorage换成类私有属性 private readonly CUSTOM_HEADER_KEY = 'HeaderName'; setHeaderValue(value: string): void { sessionStorage.setItem(this.CUSTOM_HEADER_KEY, value); } getHeaderValue(): string | null { return sessionStorage.getItem(this.CUSTOM_HEADER_KEY); } clearHeaderValue(): void { sessionStorage.removeItem(this.CUSTOM_HEADER_KEY); } }
3. 修改response.interceptor.ts 拦截响应取值
import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpResponse } from '@angular/common/http'; import { Observable, tap } from 'rxjs'; import { HeaderStorageService } from './header-storage.service'; @Injectable() export class ResponseInterceptor implements HttpInterceptor { constructor(private headerStorage: HeaderStorageService) {} intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { return next.handle(request).pipe( tap(event => { if (event instanceof HttpResponse) { const headerValue = event.headers.get('HeaderName'); // 只有响应返回了目标头才更新存储值 if (headerValue) { this.headerStorage.setHeaderValue(headerValue); } } }) ); } }
4. 修改request.interceptor.ts 给请求追加头
import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; import { Observable } from 'rxjs'; import { HeaderStorageService } from './header-storage.service'; @Injectable() export class RequestInterceptor implements HttpInterceptor { constructor(private headerStorage: HeaderStorageService) {} intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { const headerValue = this.headerStorage.getHeaderValue(); // 有值才追加头,避免传空参数 if (headerValue) { request = request.clone({ setHeaders: { HeaderName: headerValue } }); } return next.handle(request); } }
5. 确认拦截器已注册
在app.module.ts的providers数组里完成注册,两个拦截器顺序不影响当前逻辑:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { RequestInterceptor } from './request.interceptor'; import { ResponseInterceptor } from './response.interceptor'; import { AppComponent } from './app.component'; @NgModule({ declarations: [AppComponent], imports: [BrowserModule], providers: [ { provide: HTTP_INTERCEPTORS, useClass: RequestInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: ResponseInterceptor, multi: true } ], bootstrap: [AppComponent] }) export class AppModule { }
内容的提问来源于stack exchange,提问作者ram4sof
相关产品推荐
相关产品推荐

