HTML5的fetch替代XMLHttpRequest吗_HTML请求老旧吗【比对】

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

Fetch 不是 XMLHttpRequest 的“替代品”,而是更现代、更符合 Promise 设计的封装;但 XMLHttpRequest 并未被废弃,仍完全可用,也不算“老旧”——只是写法和错误处理逻辑更原始。

fetch 为什么看起来更“先进”?

它原生返回 Promise,链式调用自然,不用手动管理 readyStateonload 回调;默认不带 cookie,跨域行为更明确;接口设计更贴近现代 Web API(如 Request / Response 对象)。

但要注意:

  • fetch 不会因 HTTP 状态码(如 404、500)自动 reject,需手动检查 response.okresponse.status
  • 没有原生进度监听(XMLHttpRequest.upload.onprogress 那种),大文件上传需额外封装
  • 暂不支持同步请求(XMLHttpRequestasync: false 已被弃用,实际也不该用)

XMLHttpRequest 还值得学吗?

值得。尤其在需要精细控制请求生命周期的场景:比如上传中断重试、实时上传进度、取消请求(xhr.abort())、或兼容仍需支持 IE11 的项目。

常见误判点:

  • 认为 XMLHttpRequest “过时” → 实际它仍是浏览器标准,所有现代浏览器都 100% 支持
  • 以为 fetch 能直接替换所有 XMLHttpRequest 用法 → 比如上传带进度条、或需要设置 withCredentials 且同时读取 responseText 和响应头,fetch 写起来反而绕

fetch 和 XMLHttpRequest 的关键行为差异

最常踩坑的是错误处理和凭据传递:

  • 网络失败(如断网):两者都会触发 catchfetch)或 onerrorXMLHttpRequest);但 HTTP 错误状态(如 401):前者不会进 catch,后者会进 onload 但需查 status
  • CORS 凭据:fetch 默认不发 cookie,必须显式加 credentials: 'include'XMLHttpRequest 需设 xhr.withCredentials = true
  • 超时控制:fetch 无原生 timeout 参数,得靠 AbortControllerXMLHttpRequestxhr.timeoutontimeout
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 当网络错误处理),会导致监控漏报或用户提示错乱。