fetch()是现代JavaScript发送HTTP请求的首选,但需手动检查response.ok;XMLHttpRequest适用于进度监听和中止请求;axios解决fetch痛点且支持AbortController取消请求。

fetch() 是现代 JavaScript 发送 HTTP 请求的首选方式
绝大多数新项目应直接用 fetch(),它基于 Promise、语法简洁、原生支持 CORS 和流式响应。但要注意:它默认不带 Cookie,且 4xx/5xx 状态码不会触发 reject——这和很多人直觉相反。
常见错误现象:fetch('/api/user') 返回 404 时代码仍进入 .then(),导致后续解析 response.json() 报错 Unexpected end of JSON input。
- 必须手动检查
response.ok或response.status才能区分成功与业务失败 - 发送带凭证的请求需显式传
{ credentials: 'include' } - POST 提交 JSON 数据时,记得加
headers: { 'Content-Type': 'application/json' } - IE 完全不支持
fetch(),如需兼容,得引入 polyfill 或改用XMLHttpRequest
XMLHttpRequest 仍有必要了解,尤其在维护老代码或需要精细控制时
XMLHttpRequest 虽然繁琐,但它支持上传进度监听、请求中止(abort())、同步请求(不推荐)、以及更细粒度的 readyState 控制。当你遇到“上传大文件时想显示进度条”或“用户点了取消就立刻中断请求”,XMLHttpRequest 是唯一可靠选择。
典型陷阱:xhr.onreadystatechange 回调里没判断 xhr.readyState === 4 就直接读 xhr.responseText,结果拿到空值或中间状态。
立即学习“Java免费学习笔记(深入)”;
- 务必在
if (xhr.readyState === 4)内处理响应 - 用
xhr.addEventListener('load', handler)比onreadystatechange更清晰 - 设置超时需在
open()后、send()前赋值xhr.timeout = 10000 - 同步请求(
async: false)会阻塞主线程,已在现代浏览器中被弃用
axios 不是内置 API,但已成为事实标准的封装库
如果你的项目允许引入第三方依赖,axios 解决了 fetch() 的多数痛点:自动抛出异常、默认携带 Cookie、请求/响应拦截器、取消请求能力(CancelToken 或 AbortController)、以及更友好的错误结构。
注意版本差异:v0.27+ 开始原生支持 AbortController,旧版用 CancelToken.source();配置项如 baseURL、timeout、withCredentials 都是常用且易配错的地方。
- 全局配置慎用
axios.defaults.withCredentials = true,可能意外泄露凭证到第三方域名 - 拦截器里修改请求体后,记得返回
config,否则请求会消失 -
axios.get(url, { params: { id: 1 } })自动拼 query,但axios.post(url, data)默认以 JSON 形式提交
不要忽略 AbortController:所有现代方案都该支持取消请求
用户跳转页面、输入框快速连打、弹窗关闭等场景下,未完成的请求若继续执行并更新状态,极易引发竞态 bug(比如后发的请求先返回,覆盖了最新数据)。AbortController 是统一解决方案,fetch()、axios(v0.22+)、甚至 XMLHttpRequest(通过 xhr.signal)都支持。
容易被忽略的一点:控制器实例不能复用。每次请求都应新建 new AbortController(),然后把 signal 传入请求选项。组件卸载时调用 controller.abort() 即可。
- React 中常配合
useEffect清理函数使用 - Vue 3 的
onBeforeUnmount同理 - 不要试图在多个请求间共享一个
AbortController,abort 后信号不可重用











