fetch() 更适合现代项目:原生支持 promise、更安全、错误处理清晰,但需手动解析 json、添加超时控制、设置 credentials 及回退 xmlhttprequest 处理上传进度;xmlhttprequest 仍适用于细粒度控制和 ie11 兼容。

原生 XMLHttpRequest 和现代 fetch() 都是异步请求的底层实现,所谓“HTML Ajax”并不存在——Ajax 本身不是 HTML 的一部分,而是 JavaScript 发起异步 HTTP 请求的技术统称。用错术语或混用概念,反而会导致调试困难、兼容性误判。
为什么 fetch() 比 XMLHttpRequest 更适合现代项目
fetch() 是 Promise 原生支持的 API,避免回调地狱;默认不带 cookie,更安全;错误处理逻辑更清晰(注意:404 或 500 不会 reject,只有网络失败才 throw)。但它的默认行为也容易踩坑:
-
fetch()不自动解析 JSON:必须显式调用response.json() - 没有超时控制:需用
AbortController手动实现 - 不发送 cookie:跨域请求需加
{ credentials: 'include' } - 不支持上传进度监听:大文件上传仍得回退到
XMLHttpRequest
XMLHttpRequest 还值得学吗
值得,尤其在需要细粒度控制的场景下。比如上传大文件时监听 upload.onprogress,或兼容 IE11(fetch() 不支持)。但要注意几个硬伤:
-
XMLHttpRequest的readyState === 4不代表成功,必须检查status >= 200 && status - 手动处理 JSON 需要
JSON.parse(xhr.responseText),出错易被吞掉 - 设置请求头必须在
xhr.open()之后、xhr.send()之前 - IE 中
xhr.responseType = 'json'不生效,只能靠JSON.parse()
真正影响异步体验的不是 API,而是请求策略
换用 fetch() 或封装库不会自动提升性能。关键在怎么用:
- 避免重复请求:对相同参数的 GET 请求做内存缓存(如用
Map存url → Promise) - 合并请求:多个关联数据(如用户信息 + 权限列表)优先考虑后端聚合接口,而非前端串行/并行发多次
- 降级容错:
fetch()失败时,可 fallback 到本地 mock 数据或上一次有效响应(需业务允许) - 取消冗余请求:路由跳转或输入框防抖中,用
AbortController中止未完成的fetch()
最常被忽略的一点:后端接口响应时间远大于前端请求 API 差异带来的毫秒级变化。优化应从 Network Tab 查起——先确认是 DNS、TLS、TTFB 还是后端慢,而不是一上来就重写请求逻辑。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











