深入探究:手动编写 Ajax 请求与异步操作
在现代 Web 开发中,Ajax 技术扮演着至关重要的角色,它让我们能够在不刷新整个页面的情况下,通过异步方式获取数据并对页面进行局部刷新。今天,我们将一起深入探究 Ajax 技术,并通过手写代码的方式来理解其工作原理。
首先,让我们从头开始,逐行分析一个手动编写 Ajax 请求的示例代码,并详细解释其中的注释。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ajax</title>
</head>
<body>
<script>
// 定义一个函数 fetchJSONData,用于发送 Ajax 请求并获取数据
const fetchJSONData = function(url) {
// 返回一个 Promise 对象,用于处理异步操作
return new Promise((resolve, reject) => {
// 创建 XMLHttpRequest 对象,用于发送 HTTP 请求
const xhr =
XMLHttpRequest
? new XMLHttpRequest()
: new ActiveXObject('Microsoft.XMLHTTP');
// 初始化 HTTP 请求
xhr.open('GET', url, false);
// 监听 XMLHttpRequest 对象的状态变化
xhr.onreadystatechange = function() {
// 当请求完成时执行以下操作
if (xhr.readyState !== 4) return;
// 根据 HTTP 状态码判断请求结果
if (xhr.status === 200 || xhr.status === 304) {
// 如果请求成功,则调用 resolve 方法并传入响应数据
resolve(xhr.responseText);
} else {
// 如果请求失败,则调用 reject 方法并传入错误信息
reject(new Error(xhr.responseText));
}
};
// 发送 HTTP 请求
xhr.send();
});
};
// 使用 async/await 语法糖来处理异步操作
(async function() {
// 调用 fetchJSONData 函数发送 Ajax 请求
const p = fetchJSONData('https://api.github.com/users/shunwuyu/repos');
console.log('....');
console.log(p); // 输出 Promise 对象的状态和值
// 等待 Promise 对象的状态变为 resolved,并获取返回的数据
const res = await p;
console.log(p, res); // 输出 Promise 对象和返回的数据
})();
</script>
</body>
</html>
让我们一行一行地解释这段代码:
- 首先,我们定义了一个名为
fetchJSONData
的函数,用于发送 Ajax 请求并获取数据。 - 然后,在函数内部,我们返回一个 Promise 对象,以便处理异步操作。Promise 是 JavaScript 中用于处理异步操作的一种机制。
- 在 Promise 的构造函数中,我们创建了一个 XMLHttpRequest 对象(XMLHttpRequest 是一个内建对象,用于发送 HTTP 请求)。
- 接下来,我们调用
open
方法来初始化 HTTP 请求,使用 GET 方法和指定的 URL。 - 我们使用
onreadystatechange
事件监听 XMLHttpRequest 对象的状态变化。当 readyState 不等于 4(请求完成)时,我们不执行任何操作。 - 当请求完成时,我们检查 HTTP 状态码(
xhr.status
)。如果状态码是 200 或者 304,表示请求成功。 - 如果请求成功,我们调用
resolve
方法并传入响应数据,将 Promise 对象的状态标记为 resolved。 - 如果请求失败,我们调用
reject
方法并传入错误信息,将 Promise 对象的状态标记为 rejected。 - 最后,我们调用
send
方法发送 HTTP 请求。 - 在主程序中,我们使用 async/await 语法糖来处理异步操作。通过将代码包装在一个自执行的 async 函数中,我们可以使用 await 来等待 Promise 对象的状态变为 resolved,并获取返回的数据。
- 我们调用
fetchJSONData
函数发送 Ajax 请求,并将返回的 Promise 对象存储在变量p
中。 - 接着,我们在控制台打印一些信息,包括 Promise 对象的状态和值。
- 最后,我们使用 await 等待 Promise 对象的状态变为 resolved,并将返回的数据存储在变量
res
中。然后,我们再次在控制台打印 Promise 对象和返回的数据。
注意下面两个小细节(可能就是进大厂的契机哦)
兼容性问题
arduino
// 兼容性 IE6.0以前 现在没什么必要 IE过去式了
const xhr =
XMLHttpRequest
? new XMLHttpRequest()
: new ActiveXObject('Microsoft.XMLHTTP')
在现代浏览器中,基本上不再需要考虑这些兼容性问题,因为现代浏览器都支持标准的XMLHttpRequest对象,无需使用ActiveXObject来创建XMLHTTP对象。
对于现代浏览器,我们可以简单地使用以下代码来创建XMLHttpRequest对象:
ini
const xhr = new XMLHttpRequest();
这样就可以满足现代浏览器的需求了。然而,如果你的应用需要支持旧版的IE浏览器,那么你可能需要考虑使用类似于你提到的兼容性写法,但需要注意的是,对于安全性和性能考量,尽量避免支持过于陈旧的浏览器。但是对于要进大厂的各位来说,这还是需要了解一下的。
xhr.status === 304
当xhr.status
的值为304时,表示请求的资源在客户端的缓存中仍然是有效的,服务器告知客户端可以直接使用缓存的数据,不需要重新获取。这是一种优化机制,被称为HTTP缓存。
在这种情况下,通常可以省略对响应数据的处理,直接使用之前缓存的数据即可。这有助于提高页面加载速度和减少网络流量。
请注意,304状态码只能在使用了适当的缓存策略(例如设置了合适的Cache-Control头部)的情况下才会返回,并且浏览器会自动处理这种情况。因此,在JavaScript代码中手动检查xhr.status
是否为304通常并不是必要的。
总之,当xhr.status
的值为304时,可以认为请求成功,并且可以直接使用缓存的数据。这可能也是大厂的考点之一哦!!!
通过这段代码,我们可以深入理解以下几个重要点:
-
XMLHttpRequest 对象的创建和使用:通过创建 XMLHttpRequest 对象,我们能够发送 HTTP 请求并监听其状态变化,从而实现异步获取数据的功能。
-
Promise 的使用:通过返回 Promise 对象,我们可以更好地处理异步操作,将成功和失败的情况分别交给 resolve 和 reject 处理。
-
async/await 语法糖的应用:通过 async/await 语法糖,我们可以更加优雅地处理异步操作,避免回调地狱的问题,提高代码的可读性和可维护性。
希望这篇文章能给大家带来帮助!