在前端开发的世界里,有这样一位"信使",它让网页告别了刷新就能获取新数据的时代,它让SPA(单页应用)成为可能,它就是------AJAX(Asynchronous JavaScript and XML)。今天,咱们就来聊聊这位"信使"的成长史,从"老派"的XMLHttpRequest到"现代"的Fetch API。
一、XMLHttpRequest:AJAX的"老黄牛"
要说AJAX界的"老资历",非XMLHttpRequest莫属。这位老兄虽然名字里带着"XML",但现在它可是能处理各种数据格式,一点都不"偏科"。
咱们先来看一段经典的XMLHttpRequest使用代码:
javascript
function getData() {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest(); // 创建异步对象
xhr.open('GET', 'https://mock.mengxuegu.com/mock/66585c4db462b81cb3916d3e/songer/songer', true); // 准备请求
xhr.send(); // 发送请求
// 监测请求状态
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) { // 请求成功
let data = JSON.parse(xhr.responseText); // 解析数据
resolve(data.data);
}
}
})
}
这段代码完美诠释了使用XMLHttpRequest的"四步曲":
- 创建对象 :
new XMLHttpRequest()
- 就像制作了一个"信使"机器人 - 准备请求 :
xhr.open(method, url, async)
- 告诉"信使"要去哪儿、做什么 - 发送请求 :
xhr.send()
- 拍拍"信使"的肩膀:"出发吧!" - 监听响应 :
xhr.onreadystatechange
- 守在门口等"信使"带回消息
这里有个小知识点:readyState
是个状态码,从0到4,分别代表"未初始化"、"已打开"、"已发送"、"已接收部分数据"、"请求完成"。只有当它变成4,并且status
是200的时候,才说明"信使"圆满完成了任务。
二、Fetch API:AJAX界的"小鲜肉"
随着JavaScript的发展,一位名叫Fetch API的"小鲜肉"横空出世。它基于Promise,使用链式调用,代码更加简洁优雅,很快就赢得了前端开发者的喜爱。
咱们来看看Fetch API是怎么发送请求的:
javascript
fetch('https://mock.mengxuegu.com/mock/66585c4db462b81cb3916d3e/songer/songer?page=1', {
method: 'GET'
}).then((response) => {
return response.json(); // 解析JSON数据
}).then((data) => {
console.log(data); // 处理数据
}).catch((error) => {
console.error('请求失败:', error); // 捕获错误
});
是不是感觉代码清爽了很多?Fetch API有几个明显的优势:
- 基于Promise:告别了回调地狱,代码更加扁平化
- API设计更现代:使用了ES6+的语法特性,符合现代JavaScript的编程风格
- 功能更强大:支持流式处理、跨域处理等高级特性
但Fetch API也有一些"小脾气"需要注意:
- 默认不会发送cookie,需要手动设置
credentials: 'include'
- 不会自动拒绝HTTP错误状态码(如404、500),需要手动检查
response.ok
- 不支持超时设置,需要自己封装
三、实战对比:两位"信使"的PK
为了更直观地感受两位"信使"的差异,咱们来做个小实验。假设我们要获取歌手列表并显示在页面上,看看它们是怎么工作的。
使用XMLHttpRequest的版本:
javascript
// 点击按钮获取数据
btn.addEventListener('click', () => {
// 获取歌手数据
getData().then((data) => {
renderList(data); // 渲染列表
})
});
function getData() {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://mock.mengxuegu.com/mock/66585c4db462b81cb3916d3e/songer/songer', true);
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
let data = JSON.parse(xhr.responseText);
resolve(data.data);
}
}
})
}
function renderList(arr) {
let list = document.getElementById('list');
for (let i = 0; i < arr.length; i++) {
let item = arr[i];
let li = document.createElement('li');
li.innerText = `${item.name} -- ${item.songsCount}`;
list.appendChild(li);
}
}
使用Fetch API的版本:
javascript
btn.addEventListener('click', () => {
fetch('https://mock.mengxuegu.com/mock/66585c4db462b81cb3916d3e/songer/songer?page=1')
.then(response => response.json())
.then(data => {
renderList(data.data); // 渲染列表
})
.catch(error => console.error('获取数据失败:', error));
});
// renderList函数与上面相同
通过对比,我们可以看到Fetch API的代码更加简洁明了,链式调用让逻辑更加清晰。但XMLHttpRequest作为"老黄牛",兼容性更好,在一些旧浏览器上也能正常工作。
四、如何选择:没有最好,只有最适合
既然两位"信使"各有千秋,那我们在实际开发中该如何选择呢?这里给大家几个小建议:
- 如果项目需要兼容IE浏览器:老老实实用XMLHttpRequest吧,它的兼容性没话说
- 如果是现代项目,且使用了Promise或async/await:果断选择Fetch API,它的语法更现代,代码更优雅
- 如果需要处理复杂的请求场景:可以考虑使用Axios等第三方库,它们基于XMLHttpRequest封装,提供了更多便捷的功能
写在最后
从XMLHttpRequest到Fetch API,AJAX技术的发展见证了前端开发的进步。无论是"老黄牛"还是"小鲜肉",它们的存在都是为了让前后端通信更加高效、便捷。
作为前端开发者,我们不需要纠结于哪个技术更"高级",而是要根据实际需求选择最合适的工具。毕竟,能解决问题的技术,就是好技术!
希望这篇文章能让你对AJAX技术有更深入的了解。如果你有任何疑问,或者有更好的使用技巧,欢迎在评论区留言讨论!
小贴士:在实际开发中,为了处理Fetch API的一些"小脾气",我们可以封装一个通用的请求函数,添加超时处理、错误处理等功能,让API调用更加健壮哦!