文章目录
JavaScript原生AJAX技术详解:XMLHttpRequest与Fetch API的全面解析
一、原生AJAX概述
AJAX(Asynchronous JavaScript and XML)是一种在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。JavaScript原生实现AJAX的方式主要有两种:
- XMLHttpRequest(XHR):传统的AJAX实现方式,自IE5开始支持,是早期Web开发的核心异步请求方案。
- Fetch API:ES6引入的现代异步请求接口,基于Promise设计,语法更简洁,是XHR的替代方案。
二、两种原生AJAX方式的详细介绍
1. XMLHttpRequest(XHR)
XMLHttpRequest是最早的原生AJAX实现,通过创建XMLHttpRequest对象发起HTTP请求,支持同步/异步操作,可处理多种数据格式(XML、JSON、文本等)。
基本使用步骤:
- 创建
XMLHttpRequest实例 - 配置请求(方法、URL、同步/异步)
- 注册事件监听(如
onreadystatechange处理响应) - 设置请求头(可选,如
Content-Type) - 发送请求(
send())
代码示例(GET请求):
// 创建XHR实例
const xhr = new XMLHttpRequest();
// 配置请求:方法、URL、是否异步
xhr.open('GET', 'https://api.example.com/data', true);
// 设置请求头(可选)
xhr.setRequestHeader('Accept', 'application/json');
// 监听状态变化
xhr.onreadystatechange = function() {
// readyState=4表示请求完成,status=200表示成功
if (xhr.readyState === 4) {
if (xhr.status === 200) {
try {
const data = JSON.parse(xhr.responseText);
console.log('请求成功:', data);
} catch (e) {
console.error('解析响应失败:', e);
}
} else {
console.error('请求失败,状态码:', xhr.status);
}
}
};
// 发送请求
xhr.send();
代码示例(POST请求):
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/submit', true);
// 设置POST请求的Content-Type
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
console.log('提交成功:', xhr.responseText);
} else {
console.error('提交失败:', xhr.statusText);
}
}
};
// 发送JSON数据
const postData = { name: '张三', age: 25 };
xhr.send(JSON.stringify(postData));
2. Fetch API
Fetch API是ES6推出的现代异步请求接口,基于Promise设计,语法更简洁,支持链式调用和async/await,更符合现代JavaScript开发习惯。
基本使用特点:
- 默认返回Promise对象,避免回调地狱
- 响应处理需显式调用
response.json()/response.text()等方法 - 仅在网络错误时才会reject,HTTP错误状态(如404、500)不会触发reject
代码示例(GET请求,Promise链式):
fetch('https://api.example.com/data', {
method: 'GET',
headers: {
'Accept': 'application/json'
}
})
// 第一步:检查响应状态
.then(response => {
if (!response.ok) {
throw new Error(`HTTP错误,状态码:${response.status}`);
}
// 第二步:解析响应为JSON
return response.json();
})
// 第三步:处理数据
.then(data => {
console.log('请求成功:', data);
})
// 捕获错误(网络错误或自定义错误)
.catch(error => {
console.error('请求失败:', error.message);
});
代码示例(POST请求,async/await):
async function submitData() {
try {
const response = await fetch('https://api.example.com/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ name: '张三', age: 25 }) // 请求体
});
if (!response.ok) {
throw new Error(`提交失败,状态码:${response.status}`);
}
const result = await response.json();
console.log('提交成功:', result);
} catch (error) {
console.error('请求错误:', error.message);
}
}
// 调用函数
submitData();
三、两种方式的优缺点对比
| 特性 | XMLHttpRequest | Fetch API |
|---|---|---|
| 语法 | 基于事件回调,较繁琐 | 基于Promise,支持链式调用和async/await |
| 兼容性 | 兼容所有浏览器(包括IE5+) | IE不支持,需使用polyfill(如whatwg-fetch) |
| 同步请求 | 支持(open()第三个参数设为false) | 不支持(仅异步) |
| 错误处理 | 通过status判断,需在onreadystatechange中处理 | 仅网络错误reject,HTTP错误需手动判断response.ok |
| 请求中断 | 支持abort()方法 | 支持AbortController中断 |
| 默认行为 | 自动携带cookie | 默认不携带cookie,需设置credentials: 'include' |
| 进度监听 | 支持progress事件监听上传/下载进度 | 需通过ReadableStream实现,较复杂 |
| 响应类型处理 | 需手动解析responseText/responseXML | 提供json()/text()/blob()等方法自动解析 |
四、使用注意事项
-
跨域问题
无论是XHR还是Fetch,都受浏览器同源策略限制。跨域请求需服务器配置CORS(Access-Control-Allow-Origin等响应头),否则会触发跨域错误。 -
数据解析
- XHR需手动通过
JSON.parse()解析JSON响应,注意处理解析错误。 - Fetch的
response.json()返回Promise,需二次then或await,且仅适用于JSON格式。
- XHR需手动通过
-
错误处理
- XHR需同时判断
readyState === 4和status(200-299为成功)。 - Fetch需显式检查
response.ok(response.ok等价于status >= 200 && status < 300),否则需手动抛出错误。
- XHR需同时判断
-
兼容性处理
- 若需支持IE,优先使用XHR;使用Fetch需引入polyfill(如
whatwg-fetch)。 - 现代浏览器(Chrome、Firefox、Edge等)对Fetch支持良好。
- 若需支持IE,优先使用XHR;使用Fetch需引入polyfill(如
-
安全性
- 避免在请求中暴露敏感信息(如密钥),建议通过HTTPS传输。
- 处理响应数据时注意防XSS攻击(尤其是文本内容直接插入DOM时)。
-
请求中断
- XHR可通过
xhr.abort()中断请求。
- XHR可通过
- Fetch需配合
AbortController:
const controller = new AbortController();
fetch(url, { signal: controller.signal })
.then(response => { /* 处理响应 */ });
// 中断请求
controller.abort();
五、总结
- XMLHttpRequest:适合需要兼容旧浏览器(如IE)、需同步请求或精细控制进度的场景,但其回调式语法较繁琐,易导致代码混乱。
- Fetch API:现代项目的首选方案,基于Promise的设计更符合ES规范,配合
async/await可写出简洁清晰的异步代码,缺点是兼容性有限且错误处理需手动实现。
在实际开发中,若目标浏览器为现代浏览器,优先使用Fetch API;若需兼容IE或需要同步请求,可选择XMLHttpRequest。两者均为原生方案,无需依赖第三方库,是理解AJAX原理的基础。
1211

被折叠的 条评论
为什么被折叠?



