深入探究:手动编写 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 语法糖,我们可以更加优雅地处理异步操作,避免回调地狱的问题,提高代码的可读性和可维护性。 
希望这篇文章能给大家带来帮助!