You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免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: true
  • Access-Control-Allow-Origin设置为具体的前端域名(不能是*)

这是携带HttpOnly Cookie的必要条件,即使你排除了CORS问题,再次验证可避免隐藏的配置问题。

3. 验证拦截器顺序(当前无需调整)

当前interceptors.ts中先注册请求拦截器、再注册错误拦截器的顺序是正确的,请求拦截器先处理请求,错误拦截器后处理响应/错误,无需调整。

内容的提问来源于stack exchange,提问作者Иван

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 14:40:24