一、一句话本质
- fetch:浏览器原生的 HTTP 请求 API,基于 Promise,零依赖。浏览器内置,不用装任何包。
- axios:第三方 HTTP 客户端库(早期封装 XHR,新版也改用 fetch 实现)。在原生能力外,额外提供拦截器、超时、取消、自动 JSON 等”开箱即用”能力。
一句话:fetch 是”够用的原生工具”,axios 是”打包好的全家桶”。
二、能力对比表
| 能力 | fetch | axios |
|---|---|---|
| 第三方依赖 | 无(原生) | 需安装 axios |
| 请求 / 响应拦截器 | 需自己封装 | 原生支持 |
| 请求取消 | AbortController | CancelToken / AbortController |
| 超时控制 | 需手动 AbortController + setTimeout | timeout 配置直接搞定 |
| 自动 JSON 解析 | 需手动 res.json() | 自动序列化 / 反序列化 |
| 上传 / 下载进度 | 不支持 | onUploadProgress / onDownloadProgress |
| 浏览器 + Node 通用 | Node 18+ 内置,旧版需 polyfill | 同一套 API 两端通用 |
| 默认携带 cookie | 需 credentials: ‘include’ | 同源默认带,可配 withCredentials |
| 错误状态码处理 | 4xx/5xx 不 reject,要自己判 res.ok | 非 2xx 直接走 catch |
| 请求 / 响应转换 | 需手写 | transformRequest / transformResponse |
| 防御 XSRF | 无 | 自动带 X-XSRF-TOKEN |
三、各自的短板
fetch 的坑:
- 默认不带 cookie,跨域带凭证要写
credentials: 'include'。 - 错误状态码不 reject:404、500 也会进
then,必须自己if (!res.ok) throw ...。 - 没有进度事件,大文件上传 / 下载进度做不了。
- 旧浏览器(IE、老 Safari)不支持,需要 polyfill。
- 超时得自己用
AbortController+setTimeout拼,样板代码多。
axios 的代价:
- 多一个依赖,包体比 fetch 大(gzip 后通常可控,现代项目基本可忽略)。
- 第三方库,版本升级偶尔有 breaking change。
四、选型决策树
用 fetch 就够:
- 简单 GET / POST,不需要拦截、进度、统一错误处理。
- 现代项目(目标浏览器较新)、不想引入额外依赖。
- 小工具 / demo / 静态页。
该上 axios:
- 需要统一拦截器(自动加 token、统一错误弹窗、loading 计数)。
- 需要上传 / 下载进度。
- 需要超时、取消开箱即用(多个并发请求统一管控)。
- 同一套代码要跑在 Node 端(SSR、脚本、测试)。
- 希望错误处理一致(非 2xx 自动进 catch,不用处处判
res.ok)。
经验法则:个人小项目、纯前端简单调用 → fetch;团队项目、要统一管控请求 → axios。
五、相关阅读
- 《JavaScript Fetch方法详解》(/2026/05/2065.html) —— fetch 用法、参数、错误处理完整手册
- 《axios上传下载文本流数据》(/2021/09/17692.html) —— axios 上传下载流处理实战