Fetch 与 XMLHttpRequest 的比较
Fetch API 和 XMLHttpRequest (XHR) 都是浏览器提供的用于发起 HTTP 请求的 JavaScript API,但它们在设计理念和使用方式上有显著差异。
1. 基本设计差异
| 特性 | Fetch API | XMLHttpRequest (XHR) |
|---|---|---|
| 设计年代 | ES6 (2015) 引入的现代 API | 1999年引入的旧式 API |
| 基于 | Promise | 事件和回调函数 |
| 语法 | 更简洁,链式调用 | 较冗长,需要创建实例和设置回调 |
| 默认行为 | 默认不发送 cookies | 默认发送 cookies |
2. 功能对比
请求发起
Fetch:
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
XHR:
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data');
xhr.onload = function() {
if (xhr.status === 200) {
console.log(JSON.parse(xhr.responseText));
}
};
xhr.onerror = function() {
console.error('请求失败');
};
xhr.send();
错误处理
Fetch:
- 只有网络错误会触发 catch
- HTTP 错误状态(404, 500等)需要手动检查
response.ok
XHR:
- 通过
onerror处理网络错误 - 通过检查
status属性处理 HTTP 错误
请求取消
Fetch:
使用 AbortController:
const controller = new AbortController();
fetch(url, { signal: controller.signal });
// 取消请求
controller.abort();
XHR:
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.send();
// 取消请求
xhr.abort();
进度监控
Fetch:
- 不直接支持进度监控
- 可以通过读取流的方式实现(较复杂)
XHR:
xhr.upload.onprogress = function(e) {
console.log(`上传进度: ${e.loaded}/${e.total}`);
};
xhr.onprogress = function(e) {
console.log(`下载进度: ${e.loaded}/${e.total}`);
};
3. 优缺点分析
Fetch API 优点
- 基于 Promise,支持 async/await,代码更简洁
- 更现代的 API 设计
- 与 Service Worker 集成更好
- 更简单的请求/响应抽象
- 默认支持 CORS
Fetch API 缺点
- 不支持请求进度监控(上传/下载)
- 默认不发送 cookies
- 错误处理不如 XHR 直观
- 某些旧浏览器不支持(但现代浏览器都已支持)
XMLHttpRequest 优点
- 支持进度监控
- 更细粒度的控制
- 更广泛的浏览器支持(包括非常旧的浏览器)
- 更成熟的 API,有大量现有代码使用
XMLHttpRequest 缺点
- 回调地狱问题
- API 设计较陈旧
- 配置和使用较复杂
- 不支持 Promise,需要手动封装
4. 使用场景建议
使用 Fetch 当:
- 需要简洁的 Promise 语法
- 使用现代浏览器环境
- 不需要监控上传/下载进度
- 与 Service Worker 交互
使用 XHR 当:
- 需要支持非常旧的浏览器
- 需要监控上传/下载进度
- 需要更细粒度的请求控制
- 维护现有基于 XHR 的代码
5. 兼容性考虑
- Fetch API 在所有现代浏览器中都得到支持(Chrome 42+, Firefox 39+, Edge 14+, Safari 10.1+)
- 如果需要支持旧浏览器(如 IE),可以使用 polyfill 如
whatwg-fetch - XHR 在所有浏览器中都可用,包括 IE5+
6. 性能比较
在实际应用中,两者的性能差异通常可以忽略不计。选择应基于功能需求而非性能考虑。
总结
Fetch API 代表了 Web 开发的未来方向,提供了更现代、更简洁的接口。而 XMLHttpRequest 仍然在某些特定场景下有其价值。大多数新项目应该优先考虑使用 Fetch API,只有在需要特定功能(如进度监控)或需要支持非常旧的浏览器时才考虑使用 XMLHttpRequest。