⚡JavaScript 数据接口请求:从 XMLHttpRequest 到现代的 fetch 和 axios⚡

999 阅读4分钟

前言:

在当今数字化快速发展的世界里,Web应用的响应速度和用户体验成为了竞争的关键。想象一下,当你打开一个网页,信息瞬间呈现,交互流畅无阻——这一切的背后,离不开JavaScript强大的数据接口请求技术。从早期的XMLHttpRequest到现代的fetch API,再到功能丰富的axios库,JavaScript的数据请求方式经历了巨大的变革,每一次进化都为开发者带来了更高效、更简洁的工具。

如果当你要获取该网页:api.github.com/orgs/lemonc… 上的一些信息,你会怎么操作呢?

例如:

  • 传统方式:使用XMLHttpRequest对象发起HTTP请求,获取服务器端的数据并在不刷新页面的情况下更新DOM。
  • 现代方式:使用fetch API或axios库,它们提供了更简洁、更强大的API来进行异步数据请求。这两种方法都基于Promise,支持流式处理和其他高级特性,使得开发更加高效。

XMLHttpRequest:传统但可靠

XMLHttpRequest(通常简称为XHR)是最早的用于浏览器异步请求的技术之一。它允许网页在不重新加载整个页面的情况下向服务器发送请求,并根据返回的数据更新部分页面内容。尽管它的API相对复杂,但它仍然是一个强大且可靠的工具。

特点

  • 历史最悠久:作为最早的异步请求技术之一,它在所有浏览器中都有很好的支持。
  • 复杂API:相比现代的替代品,它的API较为冗长且复杂,需要更多的代码来完成同样的任务。
  • 适用于:如果你需要向后兼容非常老的浏览器版本,或者项目中已经大量使用了 XMLHttpRequest 并且没有迁移计划。

代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul id="memberList"></ul>
    <script>
        const  oUL=document.getElementById('memberList');
        // fetch ? js 主动拉取数据的方式 
        // fetch 的前辈 XMLHttpRequest
        const xhr =  new XMLHttpRequest(); // 实例化xhr 请求对象
        xhr.open('GET','https://api.github.com/orgs/lemoncode/members',false)
        xhr.onreadystatechange = function(){
          if(xhr.status===200&&xhr.readyState===4){ // 成功
            const data = JSON.parse(xhr.responseText);
            oUL.innerHTML=data.map(member=>`
    <li>
        <img src="${member.avatar_url}" alt="${member.login}">
        <span>${member.login}</span>
    </li>
    `).join('')
           }}
        xhr.send();
    </script>
</body>
</html>

关键点分析:

  1. 选择DOM元素
  • 使用document.getElementById('memberList')获取页面中的<ul>元素,用于后续插入成员列表。
  1. 创建并配置XHR对象
  • new XMLHttpRequest():创建一个新的XHR实例。
  • xhr.open('GET', 'https://api.github.com/orgs/lemoncode/members', false):初始化一个HTTP GET请求,指向GitHub的API端点。这里第三个参数设置为false,表示这是一个同步请求
    • 请注意,当你使用同步请求会阻塞浏览器,直到请求完成,这会导致用户体验不佳,因此不推荐在现代Web开发中使用。
  1. 处理服务器响应
  • xhr.onreadystatechange:设置一个回调函数,当服务器响应状态改变时触发 ,
    • readyState属性发生变化时触发。通过检查readyStatestatus,我们可以确定请求的状态,并根据结果采取相应的行动。
    • if (xhr.status === 200 && xhr.readyState === 4):检查请求是否成功完成(HTTP状态码200表示成功,readyState为4表示请求已完成)。
    • JSON.parse(xhr.responseText):将返回的JSON字符串解析为JavaScript对象。
    • 使用data.map(...)将每个成员的信息转换成HTML字符串,并通过.innerHTML一次性插入到<ul>元素中。
  1. 发送请求
  • xhr.send():发送请求给服务器。
  • 请求在最后一步是原因:
    • 初始化和配置请求:在发送请求之前,必须先创建并配置XMLHttpRequest对象。这包括指定请求方法(如GET、POST等)、目标URL以及是否为异步请求。
    • 设置事件监听器:为了正确处理服务器的响应,你需要提前设置好回调函数或事件监听器来捕获各种状态变化和错误情况。这些监听器应该在请求被发送之前就准备好,以确保不会错过任何重要的响应信息。
    • 确保DOM元素可用:如果你需要操作DOM元素(例如将获取的数据渲染到页面上),你应该确保这些元素已经存在于DOM树中并且可以被脚本访问。通常这意味着要在文档完全加载后执行相关代码,比如使用DOMContentLoaded事件监听器。
    • 遵循逻辑顺序:从逻辑上讲,只有当一切都准备就绪时,你才应该发起请求。如果过早地发送请求,可能会导致未定义的行为,因为某些关键设置还没有完成。

结果:

image.png

结论:

当我们使用其他两种就会发现该过程还是比较繁琐的,因为它的API相对复杂。

fetch API:简洁且基于Promise

fetch是ES6引入的一个更现代化、更简洁的方法,用于执行网络请求。它返回一个Promise,这使得处理异步操作更加直观和易于管理。此外,fetch还支持流式响应和其他高级特性。

特点:

  • 现代语法:提供了更加简洁明了的语法,减少了样板代码。
  • 基于Promise:返回一个Promise对象,便于链式调用和错误处理。
  • 缺少某些功能:例如,它不直接支持上传进度跟踪或取消请求等功能。
  • 适用于:大多数现代浏览器环境下的应用,尤其是当您希望利用原生JavaScript特性而不依赖外部库时。

代码:

可以看到使用fetch代码简洁了一些

<!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>
    
<ul id="memberList">
    </ul>
<script >
    const  oUL=document.getElementById('memberList');
    fetch('https://api.github.com/orgs/lemoncode/members')
    .then(res=>res.json())
    .then(data=>{
    oUL.innerHTML=data.map(member=>`
    <li>
        <img src="${member.avatar_url}" alt="${member.login}">
        <span>${member.login}</span>
    </li>
    `).join('')
    })
</script>
</body>
</html>

解释:

  1. 发送HTTP请求
  • 使用 fetch 发送 GET 请求到 GitHub API点https://api.github.com/orgs/lemoncode/members
  • 第一个 .then() 将响应体解析为 JSON 格式的数据。
  1. 处理响应数据
  • 第二个 .then() 接收解析后的 JSON 数据,并使用 data.map(...) 将每个成员的信息转换成 HTML 字符串。
  • .join('') 方法用于将数组中的所有字符串连接成一个完整的字符串,以便一次性插入到 DOM 中。

结论:

相比XMLHttpRequestfetch的语法更加简洁明了。

axios 库:功能丰富的HTTP客户端

axios是一个基于Promise的HTTP客户端,不仅可以在浏览器环境中使用,也可以在Node.js中使用。它提供了许多额外的功能,如自动转换JSON数据、请求/响应拦截器等,这些都使得开发变得更加高效

特点:

  • 额外特性:除了基本的请求发送外,还提供了诸如请求/响应拦截器、自动JSON转换等高级功能。
  • 跨环境兼容:既可以在浏览器中使用,也可以在Node.js环境中使用。
  • 社区支持和插件生态:拥有活跃的社区和丰富的插件生态系统,可以帮助解决各种问题并加速开发过程。
  • 适用于:大型项目或团队协作,特别是在你想要利用其提供的附加功能(如拦截器)以及跨平台开发能力的时候。

代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
    <ul id="memberList"></ul>
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            const oUL = document.getElementById('memberList');
            // 用axios 拉取数据
            axios.get('https://api.github.com/orgs/lemoncode/members')
                .then(function (response) {
                    oUL.innerHTML=response.data.map(member=>`
    <li>
        <img src="${member.avatar_url}" alt="${member.login}">
        <span>${member.login}</span>
    </li>
    `).join('')
                })
                .catch(function (error) {
                    console.error('Error:', error); // 处理错误
                });
        });
    </script>
</body>
</html>

关键分析:

  1. 引入 axios
  • 在 <head> 中通过 <script> 标签引入了 axios 库,确保可以在页面中使用 axios 发送 HTTP 请求。
  1. 确保DOM完全加载
  • 使用 document.addEventListener("DOMContentLoaded", ...) 确保 DOM 完全加载后再执行脚本,避免尝试操作尚未存在的 DOM 元素。
    • DOMContentLoaded 是一个DOM事件,它在HTML文档被完全加载和解析后触发,而无需等待样式表、图像和其他资源的加载完成。这个事件对于执行依赖于DOM结构的JavaScript代码非常有用,因为它确保了所有DOM元素都已经存在并且可以被脚本访问。
  1. 选择DOM元素
  • 使用 document.getElementById('memberList') 获取页面中的 <ul> 元素,用于后续插入成员列表。
  1. 发送HTTP请求并处理响应
  • 使用 axios.get() 方法发送 GET 请求到 GitHub API 点 https://api.github.com/orgs/lemoncode/members
  • .then() 接收响应对象,并通过 response.data 访问返回的数据(JSON格式)。
  • 使用 data.map(...) 将每个成员的信息转换成 HTML 字符串,并通过 .join('') 连接成一个完整的字符串,再赋值给 oUL.innerHTML

总结:比较与最佳实践:

综上所述,尽管 XMLHttpRequest 仍然是一个强大的工具,但在现代Web开发中,fetchaxios 提供了更简洁、更高效的解决方案。根据项目需求和个人偏好选择合适的工具是关键。

本文如果有错误的地方,请指出。