JavaScript中的XMLHttpRequest与Fetch API对比
字数 1227 2025-11-09 01:40:08
JavaScript中的XMLHttpRequest与Fetch API对比
1. 背景与概述
在JavaScript中,XMLHttpRequest(XHR) 和 Fetch API 都是用于发起网络请求的工具,但它们的设计理念、使用方式和能力存在显著差异。XHR是早期的浏览器API,而Fetch是更现代的替代方案。理解两者的区别有助于在不同场景下做出合理选择。
2. XMLHttpRequest(XHR)详解
2.1 基本用法
XHR通过实例化对象、配置参数和事件监听实现请求:
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data'); // 初始化请求
xhr.send(); // 发送请求
// 监听响应
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) { // 请求完成
if (xhr.status === 200) {
console.log(xhr.responseText);
} else {
console.error('请求失败');
}
}
};
2.2 关键特性
- readyState机制:通过0~4的状态码跟踪请求进度(如0=未初始化,4=响应完成)。
- 事件驱动:支持
onload、onerror等事件,但需手动处理错误和超时。 - 兼容性:几乎支持所有浏览器,包括老旧版本。
2.3 缺点
- 回调地狱:多个异步请求时代码嵌套复杂。
- 功能分散:需分别设置请求头、超时时间等,API设计不够直观。
3. Fetch API 详解
3.1 基本用法
Fetch基于Promise,语法更简洁:
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) throw new Error('网络响应异常');
return response.json(); // 解析JSON数据
})
.then(data => console.log(data))
.catch(error => console.error('请求失败:', error));
3.2 关键特性
- Promise链式调用:避免回调嵌套,支持
async/await。 - 响应对象封装:通过
response.ok、response.status快速判断状态。 - 流式数据处理:支持读取响应流(如
response.text()、response.blob())。
3.3 高级功能
- 自定义请求头:
fetch(url, { headers: { 'Content-Type': 'application/json' }, method: 'POST', body: JSON.stringify({ key: 'value' }) }); - 超时控制(需结合AbortController):
const controller = new AbortController(); setTimeout(() => controller.abort(), 5000); // 5秒超时 fetch(url, { signal: controller.signal });
4. 核心差异对比
| 特性 | XMLHttpRequest | Fetch |
|---|---|---|
| 语法设计 | 事件回调模式 | Promise链式调用 |
| 错误处理 | 需手动检查status码 | 默认不 reject HTTP错误(如404) |
| 请求取消 | 直接调用xhr.abort() |
需使用AbortController |
| 数据格式 | 自动解析响应文本 | 需显式调用response.json()等 |
| 跨域请求 | 需处理onerror事件 |
支持CORS模式配置 |
5. 使用场景建议
- 选择XHR的情况:
- 需要监控请求进度(如上传/下载进度条)。
- 兼容旧浏览器(如IE10以下)。
- 选择Fetch的情况:
- 现代浏览器环境,追求代码简洁性。
- 需要整合Promise或async/await的异步流程。
6. 实际示例:处理HTTP错误
XHR方式:
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
console.log(xhr.response);
} else {
console.log('错误状态码:', xhr.status);
}
};
Fetch方式:
fetch(url)
.then(response => {
if (response.ok) return response.json();
throw new Error(`HTTP ${response.status}`);
})
.catch(error => console.error(error));
7. 总结
XHR和Fetch各有优劣,Fetch更符合现代JavaScript的异步编程范式,而XHR在特定场景(如进度监控)仍有不可替代性。掌握两者的区别能帮助开发者根据实际需求灵活选择工具。