从零开始掌握 AJAX:用 XMLHttpRequest 实现异步数据请求

50 阅读3分钟

在现代 Web 开发中,通过 JavaScript 在不刷新页面的情况下动态获取并展示数据,是提升用户体验的关键技术之一。本文将围绕一段完整的 HTML 代码,详细说明如何使用原生 XMLHttpRequest 对象实现这一功能——从发起请求到解析响应,再到更新页面 DOM。


完整 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>
    <ul id="members"></ul>
    <script>
        const xhr = new XMLHttpRequest();

        // 1. 打开请求
        xhr.open('GET', 'https://api.github.com/orgs/lemoncode/members', true);

        // 2. 发送请求
        xhr.send();

        // 3. 监听状态变化
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 200) {
                const data = JSON.parse(xhr.responseText);
                const membersList = document.getElementById('members');

                data.forEach(member => {
                    const listItem = document.createElement('li');
                    listItem.textContent = member.login;
                    membersList.appendChild(listItem);
                });
            }
        };
    </script>
</body>
</html>

代码逐部分解析

1. 页面结构

<ul id="members"></ul>

页面中仅包含一个 <ul> 元素,其 id"members"。该元素初始为空,用于后续动态插入从服务器获取的组织成员信息。


2. 创建 XMLHttpRequest 对象

const xhr = new XMLHttpRequest();

通过调用 XMLHttpRequest 构造函数,创建一个用于与服务器通信的请求对象。这是原生 JavaScript 实现 AJAX 的核心。


3. 配置请求

xhr.open('GET', 'https://api.github.com/orgs/lemoncode/members', true);
  • 方法:使用 GET 请求,表示仅获取数据;
  • URL:目标接口为 GitHub 提供的公开 API:
    https://api.github.com/orgs/lemoncode/members,用于获取 lemoncode 组织的所有成员;
  • 异步标志:第三个参数设为 true,表示请求以异步方式执行,不会阻塞浏览器主线程。

4. 发送请求

xhr.send();

调用 send() 方法后,浏览器立即向指定 URL 发起 HTTP 请求。


5. 处理响应

xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        const data = JSON.parse(xhr.responseText);
        const membersList = document.getElementById('members');

        data.forEach(member => {
            const listItem = document.createElement('li');
            listItem.textContent = member.login;
            membersList.appendChild(listItem);
        });
    }
};

事件监听机制

  • onreadystatechange 是一个回调函数,每当 xhr.readyState 发生变化时都会触发。

  • 只有当满足以下两个条件时,才认为请求成功完成:

    • xhr.readyState === 4:表示整个请求-响应流程已完成;
    • xhr.status === 200:表示 HTTP 响应状态码为“OK”,即请求成功。

数据解析与 DOM 操作

  1. 解析 JSON 数据
    xhr.responseText 是服务器返回的原始字符串,通过 JSON.parse() 转换为 JavaScript 对象数组。

  2. 获取目标容器
    使用 document.getElementById('members') 获取页面中的 <ul> 元素。

  3. 遍历并渲染成员列表
    对数组中的每个 member 对象:

    • 创建一个新的 <li> 元素;
    • member.login(GitHub 用户名)设为该元素的文本内容;
    • <li> 添加到 <ul> 中。

实际运行效果

当用户打开该 HTML 页面时:

  1. 浏览器自动向 https://api.github.com/orgs/lemoncode/members 发起请求;
  2. 收到成功响应后,解析返回的 JSON 数据;
  3. 页面上的 <ul id="members"> 被动态填充为类似如下的结构(具体成员取决于 API 实时返回):
<ul id="members">
    <li>johnsmith</li>
    <li>janedoe</li>
    <li>devuser123</li>
    <!-- 更多成员... -->
</ul>

整个过程无需刷新页面,实现了典型的 AJAX 异步数据加载与局部更新


总结

本示例完整展示了使用原生 XMLHttpRequest 实现 AJAX 请求的标准流程:

  • 创建请求对象;
  • 配置并发送异步 GET 请求;
  • 监听状态变化;
  • 成功响应后解析 JSON 数据;
  • 动态操作 DOM 更新页面内容。

该代码结构清晰、逻辑完整,是理解传统 AJAX 技术的经典范例,也为后续学习 fetchaxios 等现代请求方式打下坚实基础。