一、一句话本质
- 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 上传下载流处理实战