一、什么是 Ajax?
Ajax(Asynchronous JavaScript and XML)是一种在不重新加载整个页面的前提下,通过 JavaScript 异步向服务器请求数据并更新部分网页内容的技术。尽管名字中包含 XML,但在现代 Web 开发中,Ajax 更常用于请求和处理 JSON 格式的数据。
Ajax 的核心价值在于:实现页面的局部刷新,提升用户体验与性能。用户无需等待整页重载,即可获取最新数据并动态渲染到界面上。
二、Ajax 的基本工作流程
使用原生 JavaScript 实现 Ajax 请求,主要依赖 XMLHttpRequest(简称 XHR)对象。其标准流程如下:
- 实例化 :创建
XMLHttpRequest对象; - 配置请求 :调用
.open(method, url, async)方法; - 发送请求 :调用
.send()方法; - 监听状态变化 :通过
onreadystatechange事件处理响应; - 解析与渲染:当请求完成且成功时,解析响应数据并更新 DOM。
1. 实例化 XMLHttpRequest
ini
const xhr = new XMLHttpRequest();
此时 xhr.readyState 为 0,表示"请求未初始化"。
2. 打开请求(open)
kotlin
xhr.open('GET', 'https://api.github.com/orgs/lemoncode/members', true);
参数说明:
method:HTTP 方法,如'GET'、'POST';url:目标接口地址;async:是否异步(true为异步,false为同步,默认为true)。
调用 open() 后,readyState 变为 1(请求已建立)。
⚠️ 注意:同步请求会阻塞主线程,导致页面卡顿,现代开发中应避免使用。
3. 发送请求(send)
ini
xhr.send();
调用后,readyState 进入 2(请求已发送),随后进入 3(服务器处理中),最终到达 4(请求完成)。
4. 监听状态变化(onreadystatechange)
ini
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
const data = JSON.parse(xhr.responseText);
// 渲染数据
}
};
readyState:表示请求的当前状态(0~4);status:HTTP 状态码,200表示成功;responseText:服务器返回的原始字符串。
只有当 readyState === 4 且 status === 200 时,才表示请求成功完成,可以安全处理数据。
三、readyState 状态详解
| 状态值 | 含义 | 说明 |
|---|---|---|
| 0 | 未初始化 | 尚未调用 open() |
| 1 | 已建立 | 已调用 open() |
| 2 | 已发送 | 已调用 send() |
| 3 | 正在处理中 | 服务器正在返回部分数据 |
| 4 | 已完成 | 整个请求过程完成,可读取响应 |
理解这些状态有助于调试网络请求问题,例如判断请求是否卡在发送阶段或服务器无响应。
四、同步 vs 异步请求
在示例代码中,若将 open() 的第三个参数设为 false(同步):
kotlin
xhr.open('GET', 'https://api.github.com/orgs/lemoncode/members', false);
则 send() 会阻塞 JavaScript 主线程,直到服务器返回结果。这意味着:
- 页面无法交互;
- 后续代码必须等请求完成才能执行;
- 用户体验极差。
因此,强烈推荐始终使用异步请求(async = true) ,并通过事件回调处理结果。
五、实战:渲染 GitHub 组织成员列表
以下是一个完整的异步 Ajax 示例,用于获取 Lemoncode 组织成员并动态渲染到页面:
ini
<ul id="members"></ul>
<script>
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.github.com/orgs/lemoncode/members', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
const members = JSON.parse(xhr.responseText);
const listHTML = members.map(user => `<li>${user.login}</li>`).join('');
document.getElementById('members').innerHTML = listHTML;
} else {
console.error('请求失败,状态码:', xhr.status);
}
}
};
xhr.send();
</script>
该代码实现了:
- 异步请求 GitHub API;
- 成功后解析 JSON 数据;
- 使用
map()和join()生成 HTML 字符串; - 通过
innerHTML更新 DOM。
六、Ajax 的局限性与现代替代方案
尽管 XMLHttpRequest 是 Ajax 的经典实现,但它存在以下问题:
- 语法冗长;
- 错误处理复杂;
- 不支持 Promise,难以链式调用。
因此,现代开发更倾向于使用:
fetch()API:基于 Promise,语法简洁;- Axios:功能强大的第三方库,支持拦截器、自动转换 JSON 等。
例如,使用 fetch 实现相同功能:
ini
fetch('https://api.github.com/orgs/lemoncode/members')
.then(response => response.json())
.then(members => {
const html = members.map(u => `<li>${u.login}</li>`).join('');
document.getElementById('members').innerHTML = html;
})
.catch(err => console.error('请求出错:', err));
代码更清晰,且天然支持异步/await。
七、总结
Ajax 是前端与后端通信的基石技术。掌握 XMLHttpRequest 的工作原理,有助于深入理解浏览器网络请求机制。虽然现代开发多用 fetch 或 Axios,但 Ajax 的核心思想------异步、局部更新、事件驱动------依然贯穿于所有数据交互场景。
通过本次学习,我认识到:
- 异步是 Web 性能的关键;
- 状态管理(readyState)是调试请求的重要依据;
- 文档化请求流程(方法、URL、参数、响应格式)能极大提升协作效率;
- 在 Vibe Coding 时代,清晰描述"我要什么数据、如何展示",比手写 XHR 更重要。
未来,我将在项目中结合 fetch 与错误边界处理,构建更健壮的数据请求层,同时继续夯实底层原理,做到"知其然,更知其所以然"。