news 2026/4/15 23:54:58

Angular后端联动04,深入浅出 Angular HTTP 拦截器:统一处理 Token 与响应

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Angular后端联动04,深入浅出 Angular HTTP 拦截器:统一处理 Token 与响应

在 Angular 应用开发中,HTTP 请求是与后端交互的核心环节。实际项目中,我们常常需要为所有请求统一添加认证 Token、统一处理响应错误(如 401 未授权、500 服务器错误),如果每个请求都单独处理这些逻辑,不仅代码冗余,还容易出现遗漏。Angular 的 HTTP 拦截器(HTTP Interceptor)正是为解决这类问题而生的最佳方案。

本文将手把手教你实现一个实用的 HTTP 拦截器,完成两大核心功能:

  1. 为所有 HTTP 请求自动添加 Token 请求头
  2. 统一捕获和处理 HTTP 响应异常

一、HTTP 拦截器核心概念

HTTP 拦截器是 Angular 提供的一种中间件机制,能够拦截应用发出的所有 HTTP 请求和响应,允许我们在请求发送前、响应返回后(或出错时)插入自定义逻辑。

拦截器基于HttpInterceptor接口实现,核心是intercept方法,该方法接收两个参数:

  • req: HttpRequest<any>:待处理的请求对象(不可直接修改,需克隆后修改)
  • next: HttpHandler:请求处理链路的下一个处理器

二、实现步骤

1. 环境准备

确保你的 Angular 项目已正确配置,建议使用 Angular 12 + 版本(本文示例基于 Angular 16)。

2. 创建拦截器服务

首先创建一个拦截器文件http.interceptor.ts,放在core/interceptors目录下(符合 Angular 最佳实践):

import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse } from '@angular/common/http'; import { Observable, throwError, catchError } from 'rxjs'; import { Router } from '@angular/router'; import { ToastService } from '../services/toast.service'; // 自定义提示服务(可替换为你的提示组件) @Injectable() export class HttpTokenInterceptor implements HttpInterceptor { constructor( private router: Router, private toastService: ToastService // 用于全局提示错误信息 ) {} intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { // 1. 请求拦截:统一添加Token请求头 const modifiedReq = this.addTokenToRequest(request); // 2. 响应拦截:统一处理响应和错误 return next.handle(modifiedReq).pipe( catchError((error: HttpErrorResponse) => this.handleResponseError(error)) ); } /** * 为请求添加Token请求头 * @param request 原始请求对象 * @returns 克隆后的新请求对象 */ private addTokenToRequest(request: HttpRequest<unknown>): HttpRequest<unknown> { // 从本地存储获取Token(实际项目中建议封装到AuthService) const token = localStorage.getItem('auth_token'); // 如果有Token,则克隆请求并添加Authorization头 if (token) { return request.clone({ setHeaders: { 'Authorization': `Bearer ${token}`, // JWT标准格式 'Content-Type': 'application/json' // 统一设置Content-Type } }); } // 无Token则返回原始请求 return request; } /** * 统一处理响应错误 * @param error HTTP错误响应 * @returns 抛出错误供订阅者处理 */ private handleResponseError(error: HttpErrorResponse): Observable<never> { let errorMessage = '未知错误,请稍后重试'; // 根据错误类型分类处理 if (error.error instanceof ErrorEvent) { // 客户端错误(如网络异常) errorMessage = `客户端错误:${error.error.message}`; } else { // 服务端错误(根据状态码处理) switch (error.status) { case 401: // 未授权:清除Token并跳转到登录页 localStorage.removeItem('auth_token'); this.toastService.error('登录已过期,请重新登录'); this.router.navigate(['/login']); errorMessage = '登录已过期,请重新登录'; break; case 403: errorMessage = '无权限访问该资源'; break; case 404: errorMessage = '请求的资源不存在'; break; case 500: errorMessage = '服务器内部错误,请联系管理员'; break; default: errorMessage = `服务端错误 [${error.status}]:${error.message}`; } } // 全局提示错误信息 this.toastService.error(errorMessage); // 抛出错误,让请求的订阅者也能捕获 return throwError(() => new Error(errorMessage)); } }

3. 注册拦截器

创建完拦截器后,需要在 Angular 的根模块(app.module.ts)中注册,使其生效:

import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { HttpTokenInterceptor } from './core/interceptors/http.interceptor'; import { ToastService } from './core/services/toast.service'; // 引入提示服务 @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule ], providers: [ ToastService, // 注册HTTP拦截器 { provide: HTTP_INTERCEPTORS, useClass: HttpTokenInterceptor, multi: true // 允许多个拦截器(重要!) } ], bootstrap: [AppComponent] }) export class AppModule { }

4. 补充说明:自定义提示服务(ToastService)

上述代码中用到了ToastService,这是一个自定义的全局提示服务,你可以根据项目实际情况替换为 NG-ZORRO、PrimeNG 等 UI 库的提示组件,或实现一个简易版:

// core/services/toast.service.ts import { Injectable } from '@angular/core'; import { ToastrService } from 'ngx-toastr'; // 以ngx-toastr为例 @Injectable({ providedIn: 'root' }) export class ToastService { constructor(private toastr: ToastrService) {} // 错误提示 error(message: string): void { this.toastr.error(message, '错误'); } // 成功提示(可选) success(message: string): void { this.toastr.success(message, '成功'); } }

三、高级扩展技巧

1. 排除特定请求

某些请求(如登录、注册)不需要添加 Token,可在拦截器中排除:

private addTokenToRequest(request: HttpRequest<unknown>): HttpRequest<unknown> { // 排除登录接口 const excludedUrls = ['/api/auth/login', '/api/auth/register']; if (excludedUrls.some(url => request.url.includes(url))) { return request; } const token = localStorage.getItem('auth_token'); if (token) { return request.clone({ setHeaders: { 'Authorization': `Bearer ${token}` } }); } return request; }

2. 多个拦截器的执行顺序

当注册多个拦截器时,providers数组中的顺序即为拦截器的执行顺序:

  • 请求阶段:按数组顺序执行
  • 响应阶段:按数组逆序执行

例如:

providers: [ { provide: HTTP_INTERCEPTORS, useClass: InterceptorA, multi: true }, // 先执行 { provide: HTTP_INTERCEPTORS, useClass: InterceptorB, multi: true } // 后执行 ]

请求时:A → B → 发送请求响应时:B → A → 组件

四、注意事项

  1. 请求对象不可变HttpRequest是不可变对象,必须通过clone()方法修改后再返回。
  2. 避免无限循环:拦截器中如果发起新的 HTTP 请求,务必排除该请求,否则会导致无限拦截。
  3. Token 安全存储:示例中使用localStorage存储 Token,生产环境建议结合HttpOnly Cookie或加密存储。
  4. 错误处理粒度:全局拦截器处理通用错误,特定请求的个性化错误仍需在订阅处单独处理。

总结

  1. Angular HTTP 拦截器通过实现HttpInterceptor接口,可统一拦截请求和响应,避免重复代码。
  2. 请求拦截核心是克隆HttpRequest并添加 Token 头,响应拦截通过catchError统一处理不同状态码的错误。
  3. 拦截器需在根模块注册,multi: true允许注册多个拦截器,执行顺序需根据业务需求合理设置。

通过本文的实现方案,你可以快速为 Angular 项目搭建起规范的 HTTP 请求处理体系,提升代码可维护性和用户体验。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 14:31:42

紧急通知:Dify即将调整Excel格式支持策略,现在了解还不晚

第一章&#xff1a;Dify Excel 格式支持现状全解析Dify 作为一款面向开发者与业务人员的低代码 AI 应用开发平台&#xff0c;对数据导入功能提出了较高的兼容性要求。Excel 作为企业中最常用的数据交换格式之一&#xff0c;其支持程度直接影响用户的数据接入效率。目前 Dify 支…

作者头像 李华
网站建设 2026/4/16 12:27:46

撰写案例研究:展示某公司使用VibeThinker降本增效成果

VibeThinker-1.5B&#xff1a;小模型如何撬动大效益&#xff1f; 在教育科技公司“智码未来”的技术会议室里&#xff0c;CTO李岩正盯着屏幕上跳动的性能监控图表。他们刚上线的新版自动判题系统&#xff0c;在高峰期每秒处理超过300道算法题请求&#xff0c;响应延迟稳定在1.4…

作者头像 李华
网站建设 2026/4/16 12:22:34

Dify中Next.js服务端渲染错误应对策略(SSR异常深度剖析)

第一章&#xff1a;Dify中Next.js服务端渲染错误应对策略&#xff08;SSR异常深度剖析&#xff09;在Dify平台集成Next.js应用时&#xff0c;服务端渲染&#xff08;SSR&#xff09;异常是常见的技术挑战。由于SSR在服务器端执行组件渲染&#xff0c;涉及上下文环境、依赖加载和…

作者头像 李华
网站建设 2026/4/16 15:37:21

Dify文档路径配置避坑指南:资深工程师不愿透露的10年经验

第一章&#xff1a;Dify文档保存路径的核心机制Dify 作为一个开源的 LLM 应用开发平台&#xff0c;其文档与配置文件的持久化机制依赖于清晰定义的路径管理策略。系统通过环境变量与默认规则相结合的方式&#xff0c;确保文档在不同部署环境下的一致性与可追溯性。配置驱动的存…

作者头像 李华
网站建设 2026/4/16 14:00:10

汇编语言全接触-72.Win32程序的命令行参数

在 Dos 汇编中&#xff0c;psp 段的 0080H 开始的位置就是命令行参数&#xff0c;在 Win32汇编中&#xff0c;我们获得命令行参数的方法是使用 Api - GetCommandLine&#xff0c;它没有输入参数&#xff0c;返回的是指向命令行的指针&#xff0c;返回的字符串中&#xff0c;包含…

作者头像 李华
网站建设 2026/4/15 22:07:52

计算机毕设Java金象传动公司工资管理信息系统开发 基于Java的金象传动企业薪酬管理信息化系统构建 Java技术驱动的金象传动公司薪资管理系统开发

计算机毕设Java金象传动公司工资管理信息系统开发k5gpm9&#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。随着信息技术的飞速发展&#xff0c;企业对高效、便捷的管理系统的依赖程…

作者头像 李华