news 2026/7/7 14:38:07

【前端知识点总结】请求/响应拦截器的介绍

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【前端知识点总结】请求/响应拦截器的介绍

在现代前端应用中,与后端服务的 HTTP 通信是项目的命脉。我们频繁地发起请求、处理响应。但如果每个请求都需要手动处理通用逻辑(如添加 token、错误处理),代码将变得冗余、难以维护。这时,拦截器便应运而生,它如同我们与服务器之间的“智能关卡”,赋予了我们在请求发送前和响应返回后执行自定义逻辑的强大能力。

1. 什么是拦截器?为什么需要它?

拦截器,顾名思义,是在 HTTP 请求或响应的传输过程中“拦截”它们,并在其被 then 或 catch 处理之前,执行一段特定的代码。

大多数主流 HTTP 客户端库,如 Axios,都内置了拦截器机制。它分为两种:

  1. 请求拦截器:在请求发送到服务器之前执行。
  2. 响应拦截器:在服务器返回响应,但在 Promise 的 then 或 catch 处理之前执行。

一个没有拦截器的痛点场景:

想象一下,你的应用中每个 API 请求都需要:

  1. 携带一个身份验证令牌。
  2. 显示一个全局的加载动画。
  3. 统一处理各种 HTTP 错误码(如 401 未授权、500 服务器错误)。

你的代码可能会是这样:

// 请求 A function fetchUserA() { showLoading(); const token = localStorage.getItem('token'); axios.get('/api/user/a', { headers: { Authorization: `Bearer ${token}` } }) .then(response => { // ...处理成功逻辑 }) .catch(error => { if (error.response?.status === 401) { redirectToLogin(); } else if (error.response?.status === 500) { showError('服务器错误'); } else { showError('网络异常'); } }) .finally(() => { hideLoading(); }); } // 请求 B function fetchUserB() { showLoading(); const token = localStorage.getItem('token'); axios.get('/api/user/b', { headers: { Authorization: `Bearer ${token}` } }) .then(response => { // ...处理成功逻辑 }) .catch(error => { // ...完全相同的错误处理逻辑 }) .finally(() => { hideLoading(); }); }

这简直是维护的灾难!代码高度重复,逻辑耦合严重。而拦截器,正是解决这类问题的“银弹”。

2. 拦截器核心应用场景

让我们看看拦截器如何优雅地解决上述问题。

场景一:请求拦截器 —— 统一处理认证与信息

请求拦截器最常见的用途是自动添加认证信息

// src/utils/request.js import axios from 'axios'; const service = axios.create({ baseURL: '/api' }); // 添加请求拦截器 service.interceptors.request.use( (config) => { // 在发送请求之前做些什么 const token = localStorage.getItem('token'); if (token) { // 如果 token 存在,则统一在请求头中添加 Authorization 字段 config.headers.Authorization = `Bearer ${token}`; } // 可以在这里添加其他通用信息,如请求ID、时间戳等 // config.headers['X-Request-ID'] = generateUUID(); return config; // 必须返回 config,否则请求将无法发送 }, (error) => { // 对请求错误做些什么 console.error('Request Error:', error); return Promise.reject(error); } );

现在,所有通过这个 service 实例发起的请求,都会自动带上 Authorization 头,业务代码无需再关心此事。

场景二:响应拦截器 —— 统一处理响应与错误

响应拦截器是处理通用逻辑的另一个关键环节,主要用于数据格式化错误处理

// src/utils/request.js (接上文) // 添加响应拦截器 service.interceptors.response.use( (response) => { // 2xx 范围内的状态码都会触发该函数。 // 对响应数据做点什么,例如:直接返回我们关心的 data 部分 const res = response.data; // 假设后端约定,所有成功响应的 code 都是 0 if (res.code !== 0) { // 如果 code 不是 0,说明业务逻辑上存在错误 showError(res.message || '业务错误'); return Promise.reject(new Error(res.message || 'Error')); } else { // 返回真正的业务数据 return res.data; } }, (error) => { // 超出 2xx 范围的状态码都会触发该函数。 // 对响应错误做点什么 if (error.response) { switch (error.response.status) { case 401: // 未授权,token 失效或过期 showError('登录已过期,请重新登录'); // 清除本地 token 并跳转到登录页 localStorage.removeItem('token'); redirectToLogin(); break; case 403: showError('没有权限访问'); break; case 404: showError('请求的资源不存在'); break; case 500: showError('服务器内部错误'); break; default: showError(`请求失败: ${error.response.status}`); } } else if (error.request) { // 请求已发出,但没有收到响应 showError('网络连接异常,请检查网络'); } else { // 在设置请求时触发了错误 showError('请求配置错误'); } return Promise.reject(error); // 将错误继续传递下去,方便业务层做特定处理 } );

经过这样的配置,我们的业务代码变得异常简洁:

// 简洁的业务代码 import request from '@/utils/request'; export function fetchUserA() { return request.get('/user/a'); // 自动携带token,自动处理错误,自动返回 data } export function fetchUserB() { return request.get('/user/b'); }


3. 企业级开发中的拦截器最佳实践

在企业级项目中,拦截器的使用需要更加规范和健壮。以下是几条重要的最佳实践。

实践一:封装统一的请求模块

❗❗❗永远不要在组件中直接使用 axios!应该创建一个统一的请求模块(如 src/utils/request.js),在该模块中创建 axios 实例并配置所有拦截器。所有业务代码都应通过导入这个模块来发起请求。

这样做的好处是:

  • 统一配置:所有 baseURL、timeout、拦截器逻辑都集中在一处。
  • 易于替换:未来如果想从 Axios 迁移到 fetch 或其他库,只需修改这一个文件,而不用改动全业务代码。
  • 职责分离:将网络通信的底层逻辑与业务逻辑解耦。

实践二:Token 刷新与无感刷新

在企业应用中,Token(尤其是 JWT)有过期时间。当 Token 过期时,用户会频繁被踢下线,体验极差。拦截器可以实现无感刷新 Token

核心流程:

  1. 响应拦截器捕获到 401 错误。
  2. 判断是否为 Token 过期(而非无效)。
  3. 如果是,则发起一个刷新 Token 的请求到后端(使用 refresh_token )。
  4. 如果刷新成功,将新的 access_token 存入本地存储,并重新发送刚才失败的请求。
  5. 如果刷新失败,则说明用户需要重新登录,引导其跳转。

关键点:

防止并发刷新:当多个请求同时返回 401 时,应确保只发送一个刷新请求。可以使用一个标志位(如 isRefreshing )和一个待处理请求队列来实现。

失败处理:刷新 Token 的请求本身也可能失败,需要有兜底逻辑(如强制登出)。

实践三:取消重复请求

在某些场景下,用户快速点击按钮可能会发起多个完全相同的请求,造成服务器压力和数据混乱。拦截器可以帮助我们取消正在进行的重复请求。

实现思路:

  1. 在请求拦截器中,为每个请求生成一个唯一的 key (如 method + url + params )。
  2. 维护一个 Map 或 Object 来存储每个 key 对应的 CancelToken 。
  3. 当新请求进来时,检查其 key 是否已存在于 Map 中。
  4. 如果存在,则取消上一次的请求,并用新的 CancelToken 覆盖它。
  5. 请求完成后(无论成功失败),从 Map 中移除该 key 。

Axios 的 CancelToken (在新版本中推荐使用 AbortController )是实现此功能的关键。

实践四:请求/响应日志与监控

在开发和生产环境中,对请求响应进行日志记录是排查问题的关键。

  • 开发环境:可以在拦截器中 console.log 请求的 config 和响应的 data ,方便调试。
  • 生产环境:可以将请求失败、API 耗时过长等关键信息上报到监控系统(如 Sentry、Fundebug),帮助团队快速发现和定位线上问题。
// 在响应拦截器中添加日志 service.interceptors.response.use( response => { // ...其他逻辑 const duration = Date.now() - response.config.metadata.startTime; if (duration > 3000) { // 监控慢请求 monitor.logSlowRequest(response.config.url, duration); } return response.data; }, error => { // ...错误处理 monitor.logApiError(error); // 上报 API 错误 return Promise.reject(error); } ); // 在请求拦截器中记录开始时间 service.interceptors.request.use(config => { config.metadata = { startTime: Date.now() }; return config; });

4. 总结

拦截器是前端 HTTP 客户端库提供的一个强大而灵活的机制,它让我们能够以一种非侵入式的方式,在请求生命周期的关键节点注入通用逻辑。

通过合理运用拦截器,我们可以:

  • 提升代码复用性:将认证、错误处理等通用逻辑抽离,避免重复代码。
  • 增强代码健壮性:统一处理边界情况,如 Token 刷新、网络错误。
  • 优化用户体验:实现无感刷新、取消重复请求,让应用更流畅。
  • 简化业务逻辑:让开发者更专注于业务本身,而非底层通信细节。

掌握拦截器,是从“会用”一个框架到“用好”一个框架的重要进阶。在企业级开发中,一套设计良好的拦截器方案,是构建高质量、高可维护性前端应用的坚实基石。


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

玩过模拟IC的都知道,噪声仿真这玩意儿看着简单,实操起来处处是坑。最近搞到三份实战文档,从入门到射频全覆盖,咱们直接开撸

模拟ic 电路噪声仿真教学,保姆级教学 三份文档,一份82页初级教学,一份92页进阶教学,一份38页射频sp噪声。 都是有配套电路文件压缩包 直接下载,virtuoso直接使用,免安装 初级教学,有6个小案例教…

作者头像 李华
网站建设 2026/7/7 11:33:53

如何使用AI工具助力域名投资人

关于Dynadot Dynadot是通过ICANN认证的域名注册商,自2002年成立以来,服务于全球108个国家和地区的客户,为数以万计的客户提供简洁,优惠,安全的域名注册以及管理服务。 Dynadot平台操作教程索引(包括域名邮…

作者头像 李华
网站建设 2026/7/7 12:09:26

计算机毕业设计springboot基于JavaWeb的校园物品置换网站 基于 Spring Boot 的校园闲置物品交换平台设计与实现 JavaWeb 技术驱动的校园物品置换系统开发

计算机毕业设计springboot基于JavaWeb的校园物品置换网站9g27n9 (配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。随着校园生活的日益丰富,学生们常常面临各种闲置物品…

作者头像 李华
网站建设 2026/7/7 17:46:36

MATLAB代码:参考《基于多目标算法的冷热电联供型综合能源系统运行优化》 本程序对惯性权重因...

MATLAB代码:参考《基于多目标算法的冷热电联供型综合能源系统运行优化》 本程序对惯性权重因子和学习因子进行改进 采用改进粒子群算法以运行成本和环境成本最低为目标实现了冷热电联供型综合能源系统优化运行 程序运行良好 模块化编程 注释清楚凌晨三点的实验室里&…

作者头像 李华
网站建设 2026/7/7 17:14:14

BGP实验

BGP实验报告,见word文档

作者头像 李华