Fetch 并非 XMLHttpRequest 的替代品,而是更现代的 Promise 封装;后者未被废弃,仍完全可用且适用于进度监听、取消请求等精细控制场景。

Fetch 不是 XMLHttpRequest 的“替代品”,而是更现代、更符合 Promise 设计的封装;但 XMLHttpRequest 并未被废弃,仍完全可用,也不算“老旧”——只是写法和错误处理逻辑更原始。
fetch 为什么看起来更“先进”?
它原生返回 Promise,链式调用自然,不用手动管理 readyState 和 onload 回调;默认不带 cookie,跨域行为更明确;接口设计更贴近现代 Web API(如 Request / Response 对象)。
但要注意:
-
fetch不会因 HTTP 状态码(如 404、500)自动 reject,需手动检查response.ok或response.status - 没有原生进度监听(
XMLHttpRequest.upload.onprogress那种),大文件上传需额外封装 - 暂不支持同步请求(
XMLHttpRequest的async: false已被弃用,实际也不该用)
XMLHttpRequest 还值得学吗?
值得。尤其在需要精细控制请求生命周期的场景:比如上传中断重试、实时上传进度、取消请求(xhr.abort())、或兼容仍需支持 IE11 的项目。
立即学习“前端免费学习笔记(深入)”;
常见误判点:
- 认为
XMLHttpRequest“过时” → 实际它仍是浏览器标准,所有现代浏览器都 100% 支持 - 以为
fetch能直接替换所有XMLHttpRequest用法 → 比如上传带进度条、或需要设置withCredentials且同时读取responseText和响应头,fetch写起来反而绕
fetch 和 XMLHttpRequest 的关键行为差异
最常踩坑的是错误处理和凭据传递:
- 网络失败(如断网):两者都会触发
catch(fetch)或onerror(XMLHttpRequest);但 HTTP 错误状态(如 401):前者不会进catch,后者会进onload但需查status - CORS 凭据:
fetch默认不发 cookie,必须显式加credentials: 'include';XMLHttpRequest需设xhr.withCredentials = true - 超时控制:
fetch无原生 timeout 参数,得靠AbortController;XMLHttpRequest有xhr.timeout和ontimeout
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal })
.catch(err => {
if (err.name === 'AbortError') console.log('请求已取消');
});
// 5秒后取消
setTimeout(() => controller.abort(), 5000);
什么情况下该选哪个?
简单 GET/POST 且无需进度或细粒度控制 → 优先用 fetch;需要上传进度、取消、兼容极老环境、或已有稳定 XMLHttpRequest 封装 → 没必要强行切换。
真正容易被忽略的不是“哪个更新”,而是:同一项目里混用两者时,错误分类逻辑不一致(比如把 404 当网络错误处理),会导致监控漏报或用户提示错乱。











