news 2026/6/25 18:27:31

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/6/22 14:59:43

揭秘Docker Rollout部署全流程:3个关键命令让你效率提升200%

第一章&#xff1a;揭秘Docker Rollout部署的核心价值在现代云原生架构中&#xff0c;持续交付与快速迭代已成为软件开发的关键诉求。Docker Rollout 部署模式通过容器化技术实现了应用版本的平滑过渡与高效管理&#xff0c;显著提升了系统的可用性与运维效率。为何选择Docker …

作者头像 李华
网站建设 2026/6/20 15:17:02

视频硬字幕一键提取终极指南:告别手动打字,AI智能识别

视频硬字幕一键提取终极指南&#xff1a;告别手动打字&#xff0c;AI智能识别 【免费下载链接】video-subtitle-extractor 视频硬字幕提取&#xff0c;生成srt文件。无需申请第三方API&#xff0c;本地实现文本识别。基于深度学习的视频字幕提取框架&#xff0c;包含字幕区域检…

作者头像 李华
网站建设 2026/6/16 14:32:53

社区支持怎么样?VibeThinker是否有活跃的讨论群组?

VibeThinker-1.5B&#xff1a;小模型如何实现高精度数学与编程推理&#xff1f; 在当前AI大模型动辄千亿参数、训练成本破百万美元的背景下&#xff0c;一个仅15亿参数的模型竟能在数学竞赛题和算法挑战中击败数百倍体量的对手——这听起来像技术神话&#xff0c;但VibeThinker…

作者头像 李华
网站建设 2026/6/24 13:46:25

三极管工作状态解析:全面讲解放大区应用要点

三极管放大区实战指南&#xff1a;从原理到零失真设计你有没有遇到过这样的情况&#xff1f;电路明明照着参考图搭的&#xff0c;电源也加了&#xff0c;信号也输入了——可输出波形就是不对劲&#xff1a;要么削顶&#xff0c;要么发闷&#xff0c;甚至一通电就发热烧管。如果…

作者头像 李华
网站建设 2026/6/21 7:19:18

如何评估其实际效果?给出五个典型测试题参考答案

VibeThinker-1.5B-APP&#xff1a;小模型如何实现高精度推理&#xff1f;五道典型题深度解析 在AI大模型动辄千亿参数、训练成本破千万美元的今天&#xff0c;一个仅用7,800美元训练、参数量只有15亿的模型&#xff0c;竟能在数学竞赛和算法编程任务中击败数十倍规模的对手——…

作者头像 李华