Axios拦截器 -- 请求拦截器和响应拦截器

Axios 拦截器时机 + 拦截器基础

前置:拦截器基础(是什么?为什么用?怎么注册?)

在讲 "拦截时机" 前,先明确拦截器核心基础 ------ 这是理解 "自动触发、触发时机" 的前提:

1. 拦截器的定义

Axios 拦截器(Interceptor)是 Axios 提供的全局钩子函数,分为「请求拦截器」和「响应拦截器」,可在 "请求发出前" 和 "响应返回后、业务代码处理前" 统一处理请求 / 响应,是 Axios 核心扩展能力。

2. 拦截器的核心价值

  • 减少重复代码:如所有请求加 token、所有响应简化数据,无需在每个请求里重复编写;
  • 统一管控流程:如全局处理加载动画、统一捕获错误(401 跳登录、500 服务器提示);
  • 灵活控制请求 / 响应:如请求前校验参数、响应后过滤无用数据。

3. 拦截器的核心注册语法

推荐「实例拦截器」(避免污染全局),核心语法如下:

javascript

javascript 复制代码
import axios from 'axios';

// 1. 创建自定义Axios实例(项目主流用法,隔离全局配置)
const service = axios.create({
  baseURL: 'https://api.example.com', // 接口基准地址
  timeout: 5000 // 请求超时时间(5秒)
});

// 2. 注册请求拦截器:请求发出前预处理
// 入参:成功回调(必须返回config,否则请求终止)、失败回调(必须返回reject)
const requestInterceptor = service.interceptors.request.use(
  (config) => {
    // 业务示例:统一给请求头加token(最常用场景)
    const token = localStorage.getItem('token');
    if (token) config.headers.Authorization = `Bearer ${token}`;
    return config; 
  },
  (error) => {
    // 请求拦截失败(如配置错误),终止流程并抛错给后续catch
    return Promise.reject(error);
  }
);

// 3. 注册响应拦截器:响应返回后、业务处理前预处理
const responseInterceptor = service.interceptors.response.use(
  (response) => {
    // 业务示例:简化响应数据,业务层直接获取data(无需写response.data)
    return response.data;
  },
  (error) => {
    // 业务示例:统一错误处理(401未授权自动跳登录)
    if (error.response?.status === 401) {
      window.location.href = '/login'; // 跳转登录页
    }
    // 响应拦截失败,抛错给业务层catch
    return Promise.reject(error);
  }
);

// 4. 移除拦截器(可选:页面销毁/无需拦截时清理)
// service.interceptors.request.eject(requestInterceptor);
// service.interceptors.response.eject(responseInterceptor);

4. 拦截器的核心特点

  • 链式执行:支持多拦截器,请求拦截器 "后注册先执行" (栈结构)、响应拦截器 "先注册先执行"(队列结构);
  • 非侵入式:不修改原始请求 / 响应逻辑,仅做 "预处理 / 后处理";
  • 可终止流程:返回 Promise.reject(error) 可直接终止请求 / 响应流程,触发后续 catch。

核心结论:拦截器触发时机(与 get/then/catch 的关系)

✅ 请求拦截器 :不是 "调用axios.get()前" 执行,而是调用axios.get()后、Axios 真正发送 HTTP 请求前 执行;

✅ 响应拦截器 :服务端返回响应后、.then()/.catch()执行前 执行;

✅ 整体符合 "请求 / 响应被 then/catch 处理前拦截" 的定义(请求拦截:拦截即将发出的请求;响应拦截:拦截即将交给业务的响应)。


一、纠正 "get 之前执行拦截器" 的误解

易混淆点:

  • 拦截器是提前注册 (如项目初始化时),但仅调用axios.get()(发起请求)时才触发;
  • 触发后先执行请求拦截器,再发送 HTTP 请求,而非 "未调用 get 就执行拦截器"。

通俗类比

  • 注册请求拦截器 = 餐厅提前制定 "接单后核对订单" 的规则;
  • 调用axios.get() = 你向餐厅下单(发起请求);
  • 请求拦截器执行 = 服务员接单后、后厨做菜前,核对订单(加调料 / 确认地址);
  • 实际发送请求 = 后厨做菜并送出;
  • 响应拦截器执行 = 菜送回餐厅后、服务员交你前,检查菜品是否合格;
  • .then()/.catch() = 你吃到菜(处理成功)或吐槽(处理失败)。

二、完整执行链路(代码)

javascript

javascript 复制代码
import axios from 'axios';

// 1. 创建自定义Axios实例(隔离全局配置,项目推荐)
const service = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 5000
});

// 2. 注册请求拦截器:get调用后、发请求前执行
service.interceptors.request.use(
  (config) => {
    console.log('🔴 请求拦截器执行(get调用后,发请求前)');
    // 核心业务:给所有请求加token
    const token = localStorage.getItem('token');
    if (token) config.headers.Authorization = `Bearer ${token}`;
    return config; // 必须返回配置,请求才能继续发送
  },
  (error) => {
    console.error('🔴 请求拦截器执行失败');
    return Promise.reject(error); // 终止请求,触发catch
  }
);

// 3. 注册响应拦截器:响应返回后、then/catch前执行
service.interceptors.response.use(
  (response) => {
    console.log('🟢 响应拦截器执行(响应返回后,then/catch前)');
    return response.data; // 简化数据,业务层直接用data
  },
  (error) => {
    console.error('🟢 响应拦截器执行失败');
    // 401统一处理:登录过期跳登录页
    if (error.response?.status === 401) {
      window.location.href = '/login';
      alert('登录过期,请重新登录');
    }
    return Promise.reject(error); // 抛错给业务层catch
  }
);

// 4. 调用get发起请求(触发整个拦截器+请求链路)
console.log('📌 开始调用service.get()');
service.get('/api/test', { 
  params: { id: 123 } // URL查询参数,最终拼接为?id=123
})
.then((data) => {
  // 响应拦截器简化后,直接拿到服务端返回的原始数据
  console.log('✅ then执行(响应拦截器后):', data);
})
.catch((error) => {
  // 捕获全链路错误:拦截器失败/网络错误/服务端错误等
  console.log('❌ catch执行(响应拦截器后):', error);
});

控制台输出顺序(成功场景)

📌 开始调用service.get()

🔴 请求拦截器执行(get调用后,发请求前)

// 【底层异步发送HTTP请求,等待服务端响应】

🟢 响应拦截器执行(响应返回后,then/catch前)

✅ then执行(响应拦截器后):{...} // 直接拿到简化后的data

控制台输出顺序(失败场景:401)

📌 开始调用service.get()

🔴 请求拦截器执行(get调用后,发请求前)

// 【底层发送请求,服务端返回401】

🟢 响应拦截器执行失败

❌ catch执行(响应拦截器后):Error: Request failed with status code 401

关键结论

  • 请求拦截器:axios.get() 调用后、实际 HTTP 请求发送前执行(非 "写 get 代码前");
  • 响应拦截器:服务端返回响应后、.then()/.catch() 执行前执行;
  • 两者均实现 "请求 / 响应被 then/catch 处理前拦截" 的核心目标。

三、"拦截" 的具体行为(为什么要这个时机)

1. 请求拦截器(get 调用后,发请求前)

此时 Axios 已整合请求配置(url/params/headers 等),但未发送请求,可操作:

  • ✅ 修改配置:加 token、补 baseURL、改请求方法;
  • ✅ 校验拦截:token 过期 / 参数缺失时终止请求,避免无效请求;
  • ✅ 附加逻辑:开启加载动画、记录请求日志、取消重复请求。

2. 响应拦截器(响应返回后,then/catch 前)

此时服务端已返回响应,业务代码未处理,可操作:

  • ✅ 简化数据:仅返回response.data,简化业务层代码;
  • ✅ 统一错误:401 跳登录、404 提示资源不存在、500 提示服务器错误;
  • ✅ 数据预处理:过滤无用字段、格式化日期 / 分页数据;
  • ✅ 兜底处理:网络错误 / 超时提示 "网络异常",提升体验。

四、拦截器执行时机边界表

拦截类型 触发时机 相对于axios.get()的位置 相对于.then()/.catch()的位置 核心可操作行为
请求拦截器 调用axios.get()后,实际发请求前 调用后,发请求前 远早于(请求阶段拦截) 修改配置、校验参数、开启加载动画
响应拦截器 服务端返回响应后,.then()/.catch()前 调用 get 后的 "响应阶段" 直接在前面(响应交给业务前拦截) 简化数据、统一错误、关闭加载动画

五、总结:拦截器核心逻辑

  1. 注册与触发 :拦截器提前注册(实例 / 全局),调用axios.get()/post()时自动触发,无需手动调用;
  2. 时机核心 :调用axios.get() → 请求拦截器 → 发送请求 → 服务端响应 → 响应拦截器 → .then()/.catch();"处理前拦截":请求拦截 = 拦截即将发出的请求,响应拦截 = 拦截即将交给业务的响应;
  3. 核心价值:实现请求 / 响应的全局统一处理,减少重复代码,提升流程管控能力。
    简单记:拦截器是 Axios 给请求加的 "前置过滤器"、给响应加的 "后置处理器",axios.get()是触发这套过滤 / 处理流程的开关。
相关推荐
阿里嘎多学长1 分钟前
2026-10-13 GitHub 热点项目精选
开发语言·程序员·github·代码托管
巧克力味的桃子9 分钟前
复杂网络能控性鲁棒性研究进展
开发语言·网络·php
ShineWinsu18 分钟前
对于CSS:选择器的解析
前端·css·面试·html·web·选择器·网页
m0_5873830023 分钟前
碰碰好评卡功能落地实战 从需求梳理到上线部署全流程实操指南
java·linux·服务器·前端·javascript·vue.js·人工智能
Pu_Nine_924 分钟前
Vue‑Flow 从零入门实战|AI‑Agent 拓扑图开发
前端·javascript·vue.js
keyipatience25 分钟前
CSS 学习(1):语法、引入方式、选择器、字体与背景
前端·css·html
普通人629 分钟前
php处理百度编辑器有误html
开发语言·编辑器·html·php·1024程序员节
程序人生88829 分钟前
本地向量底座怎么搭?DocConverter Web 的 BGE 嵌入模型、ChromaDB 与外部 Milvus 接入
前端·milvus
沉下心来学鲁班37 分钟前
具身智能入门:用 Python 让 MicroDuck 机器狗学会走路
开发语言·人工智能·python·机器人
geovindu38 分钟前
rust: Chain of Responsibility Pattern (续)
开发语言·后端·设计模式·rust·责任链模式·行为模式