手写 AJAX:从零实现一个简洁的异步请求函数
前言
在现代前端开发中,fetch
和 axios
等工具库已经大大简化了异步请求的编写。但在某些情况下,我们仍然需要深入了解 AJAX 的底层实现,尤其是在学习 JavaScript 语言核心的过程中。今天,我们将从零开始,手写一个 AJAX 请求函数,并封装成一个基于 Promise
的 getJSON
方法。
什么是 AJAX?
AJAX(Asynchronous JavaScript and XML)是一种用于创建异步 Web 应用的技术,允许网页在不重新加载的情况下从服务器获取数据。现代 AJAX 主要使用 JSON 作为数据格式,而不是早期的 XML。
手写 AJAX 请求
以下是我们手写的 getJSON
方法,它通过 XMLHttpRequest
发送 GET 请求,并返回 Promise
以支持异步操作。
代码实现
xml
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>手写Ajax</title>
</head>
<body>
<script>
const getJSON = function(url) {
return new Promise((resolve, reject) => {
const xhr = window.XMLHttpRequest
? new XMLHttpRequest()
: new ActiveXObject("Microsoft.XMLHTTP"); // 兼容早期IE浏览器
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState !== 4) return;
if (xhr.status === 200 || xhr.status === 304) {
resolve(JSON.parse(xhr.responseText)); // 解析 JSON 数据
} else {
reject(new Error(`请求失败,状态码:${xhr.status}`));
}
};
xhr.send();
});
};
getJSON('https://api.github.com/orgs/lemoncode/members')
.then(data => {
console.log("请求成功:", data);
})
.catch(error => {
console.error("请求失败:", error);
});
</script>
</body>
</html>
代码解析
-
兼容性处理
- 通过
window.XMLHttpRequest
选择XMLHttpRequest
,如果浏览器不支持(如 IE 早期版本),则使用ActiveXObject
。
- 通过
-
创建异步请求
xhr.open('GET', url, true);
这里的true
代表异步操作。
-
监听
readystatechange
事件xhr.readyState === 4
代表请求已完成。xhr.status === 200 || xhr.status === 304
代表请求成功。- 解析 JSON 数据后返回。
-
使用 Promise
- 通过
resolve
返回数据,reject
处理错误,增强可读性。
- 通过
对比 fetch
API
fetch
是现代浏览器提供的原生 API,它可以用更简洁的方式来实现相同的功能,例如:
ini
fetch('https://api.github.com/orgs/lemoncode/members')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
相比之下,fetch
语法更简洁,且默认返回 Promise
,不需要手动封装。但理解 XMLHttpRequest
的底层实现对于深入学习 JavaScript 仍然很有帮助。
总结
本篇文章带你从零实现了一个 getJSON
方法,它使用 XMLHttpRequest
进行 AJAX 请求,并通过 Promise
进行封装,使得代码更易读、更符合现代 JavaScript 编程风格。虽然现在我们更多使用 fetch
或 axios
,但掌握 AJAX 的底层实现有助于我们更好地理解前端开发的本质。