Fetch 与 XMLHttpRequest 的比较

97 阅读3分钟

Fetch 与 XMLHttpRequest 的比较

Fetch API 和 XMLHttpRequest (XHR) 都是浏览器提供的用于发起 HTTP 请求的 JavaScript API,但它们在设计理念和使用方式上有显著差异。

1. 基本设计差异

特性Fetch APIXMLHttpRequest (XHR)
设计年代ES6 (2015) 引入的现代 API1999年引入的旧式 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 优点

  1. 基于 Promise,支持 async/await,代码更简洁
  2. 更现代的 API 设计
  3. 与 Service Worker 集成更好
  4. 更简单的请求/响应抽象
  5. 默认支持 CORS

Fetch API 缺点

  1. 不支持请求进度监控(上传/下载)
  2. 默认不发送 cookies
  3. 错误处理不如 XHR 直观
  4. 某些旧浏览器不支持(但现代浏览器都已支持)

XMLHttpRequest 优点

  1. 支持进度监控
  2. 更细粒度的控制
  3. 更广泛的浏览器支持(包括非常旧的浏览器)
  4. 更成熟的 API,有大量现有代码使用

XMLHttpRequest 缺点

  1. 回调地狱问题
  2. API 设计较陈旧
  3. 配置和使用较复杂
  4. 不支持 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。