贝利信息

html5的fetch API和html4的XMLHttpRequest有啥区别【对比】

日期:2026-01-03 00:00 / 作者:看不見的法師
fetch 是 Promise 驱动,XMLHttpRequest 是事件回调驱动;前者默认不带 Cookie、无上传进度支持、需 AbortController 取消,后者默认发 Cookie、支持 upload.onprogress、直接 abort() 且兼容性更强。

fetch 是 Promise 驱动,XMLHttpRequest 是事件回调驱动

这是最根本的差异:调用 fetch() 立即返回一个 Promise,你用 .then()async/await 处理响应;而 XMLHttpRequest 必须监听 onloadonerroronprogress 等事件,手动管理状态(readyState)。

这意味着:

fetch 不支持同步请求,XMLHttpRequest 支持但已被弃用

XMLHttpRequest 构造时传入 false 第三个参数可发起同步请求(阻塞主线程),但现代浏览器已禁用该能力(抛出 DOMException: Synchronous XMLHttpRequest on the main thread is not allowed)。fetch() 从设计上就不支持同步——它只能是异步的。

所以实际开发中:

fetch 默认不发 cookie,XMLHttpRequest 默认发送(同域下)

fetch()credentials 选项默认是 'omit',即跨域或同域都不带 Cookie;XMLHttpRequest 在同域下默认携带 Cookie(只要没显式设 withCredentials = false)。

常见踩坑点:

fetch('/api/user', {
  credentials: 'include'
})

fetch 对上传进度无原生支持,XMLHttpRequest 有 upload.onprogress

如果你要做大文件上传并显示进度条,XMLHttpRequest 是更直接的选择。它的 xhr.upload.onprogress 能拿到 loadedtotal 字节数;fetch() 本身不暴露上传过程,得靠 ReadableStream + TransformStream 手动分块读取并上报进度(复杂且兼容性差)。

折中方案:

实际项目里,fetch() 已成主流,但别盲目替换所有 XMLHttpRequest —— 特别是涉及上传进度、细粒度超时、或需要兼容极老环境的场景,老 API 还有它不可替代的位置。