前端 HTTP 请求:XHR vs Fetch vs Axios
把 AJAX/XHR/Fetch/Axios 放在一起理解:演进、差异、选型与常见坑。
#type / synthesis
#status / growing
#tech / network
#platform / browser
#resource / http
#resource / javascript
[!info] related notes
- 所属 MOC: http-and-frontend-networking-moc
- 概念: ajax, xhr, fetch-api, axios
- Axios 深入: Axios 请求配置, Axios 实例, Axios 拦截器, Axios 错误模型, Axios 取消请求
- 状态码与错误处理: frontend-http-status-code-handling, http-status-codes
前端 HTTP 请求:XHR vs Fetch vs Axios
范围
这篇只解决一个问题:在前端发 HTTP 请求时,这几件事分别处在什么层、有什么差异、该怎么选。
为什么要放在一起理解
- AJAX 不是 API,而是一种“局部更新、避免整页刷新”的开发实践。
- XHR/Fetch 是浏览器提供的 Web API(不同年代/不同风格)。
- Axios 是第三方库,目标是把常见工程需求(拦截器、统一错误处理、超时、取消等)做成更顺手的工具箱。
把它们混在一起写成“教程长文”时,最容易出现两类问题:
- 概念层和实现层互相污染(比如把 AJAX 当成某个函数)。
- 重复堆代码片段,但没有把关键差异讲清楚。
演进与定位
- AJAX(实践/模式) -> 常用实现曾经是 XHR(API)
- Fetch(API) -> Promise 风格 + Request/Response 对象模型
- Axios(库) -> 封装 Fetch/XHR/Node adapter,提供工程化能力
- Axios(库) -> 封装 Fetch/XHR/Node adapter,提供工程化能力
关键差异(抓住这些就够用)
- 错误语义:
- Fetch: 只有“网络失败/请求被中断”等才会 reject;HTTP 4xx/5xx 仍 resolve,需要自己判断
response.ok。 - Axios: 默认把非 2xx 当成 reject(更符合大多数业务代码直觉)。
- Fetch: 只有“网络失败/请求被中断”等才会 reject;HTTP 4xx/5xx 仍 resolve,需要自己判断
- 响应体读取:
- Fetch:
response.json()/response.text()等需要显式读,并且 body 通常只能读取一次。 - Axios: 通常直接拿
response.data。
- Fetch:
- 取消请求:
- Fetch:
AbortController。 - Axios: 现代版本也支持
AbortController(旧版有 CancelToken)。
- Fetch:
- 进度与上传:
- XHR 更容易做上传/下载进度监听(尤其是上传)。
- Fetch 对进度/上传监听相对不直观,常需要额外方案。
选型建议(工程口径)
- 小项目/原生偏好: 优先 Fetch(配合一个薄封装:统一 ok 检查、timeout、JSON 解析、错误格式化)。
- 中大型项目/需要拦截器与统一策略: Axios 更省事。
- 需要细粒度进度/兼容老环境: 仍可能会选 XHR 或基于 XHR 的封装。
下一步阅读
- 概念:ajax -> xhr -> fetch-api -> axios
- 错误处理模板:frontend-http-status-code-handling