如何避免Angular HttpRequestInterceptor清除错误状态码?
Angular 15拦截器问题:启用HttpRequestInterceptor后错误状态码丢失
我使用Angular 15开发项目,项目包含两个拦截器:HttpRequestInterceptor和ErrorInterceptor。启用HttpRequestInterceptor时,服务器返回的错误状态码及错误信息丢失;关闭该拦截器后一切正常。但我需要通过此拦截器设置withCredentials: true,让浏览器在请求头中携带HttpOnly Cookie。已通过向http://httpstat.us/404发送测试请求排除了CORS问题,求解决该拦截器问题的方案。
相关代码
HttpRequestInterceptor.ts
import { Injectable } from '@angular/core'; import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HTTP_INTERCEPTORS } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root', }) export class HttpRequestInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { req = req.clone({ withCredentials: true, }); return next.handle(req); } }
ErrorInterceptor.ts
import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse } from '@angular/common/http'; import { catchError, Observable, throwError } from 'rxjs'; @Injectable() export class ErrorInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(req).pipe( catchError((error) => { if (error instanceof HttpErrorResponse) { if (error.error instanceof ErrorEvent) { console.log('Error Event'); } else { console.log(error); switch (error.status) { case 401: // 未授权 console.log(error.statusText); break; case 403: // 禁止访问 console.log(error.statusText); break; case 404: // 资源未找到 console.log(error.statusText); break; case 503: // 服务器错误 console.log(error.statusText); break; } } } else { console.log('发生错误'); } return throwError(() => new Error(error.statusText)); }) ); } }
interceptors.ts
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { HttpRequestInterceptor } from './http.interceptor'; import { ErrorInterceptor } from './error.interceptor'; export const interceptorProviders = [ { provide: HTTP_INTERCEPTORS, useClass: HttpRequestInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }, ];
日志情况
- 启用
HttpRequestInterceptor时:浏览器日志无错误码 - 关闭
HttpRequestInterceptor时:浏览器日志显示正常错误码
解决方案
1. 保留原始错误对象
问题核心在于ErrorInterceptor中,你将原始的HttpErrorResponse替换成了普通的Error对象,导致错误状态码等关键信息丢失。修改ErrorInterceptor.ts的错误抛出逻辑,直接返回原始错误:
// 替换原来的return语句 return throwError(() => error);
原始代码return throwError(() => new Error(error.statusText));会丢弃HttpErrorResponse中的status、error等属性,上游代码无法获取完整错误信息。直接抛出原始错误即可保留所有错误细节。
2. 确认服务器响应头配置
确保服务器返回错误响应时,包含以下响应头:
Access-Control-Allow-Credentials: trueAccess-Control-Allow-Origin设置为具体的前端域名(不能是*)
这是携带HttpOnly Cookie的必要条件,即使你排除了CORS问题,再次验证可避免隐藏的配置问题。
3. 验证拦截器顺序(当前无需调整)
当前interceptors.ts中先注册请求拦截器、再注册错误拦截器的顺序是正确的,请求拦截器先处理请求,错误拦截器后处理响应/错误,无需调整。
内容的提问来源于stack exchange,提问作者Иван
相关产品推荐
相关产品推荐

