🔥 前端必考!AJAX 数据请求全解析,async true/false 区别一次搞懂
前言:AJAX 是前端开发的基石技术,也是大厂面试的高频考点。本文通过实战代码,带你彻底掌握 AJAX 请求流程、readyState 状态变化,以及 async true/false 的核心区别。建议收藏反复学习!
📌 一、什么是 AJAX?
AJAX 全称 Asynchronous JavaScript and XML(异步 JavaScript 和 XML),是一种在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页内容的技术。
javascript
┌─────────────────────────────────────────────────────────┐
│ AJAX 核心价值 │
├─────────────────────────────────────────────────────────┤
│ ✅ 局部刷新,无需整页重载 │
│ ✅ 异步通信,提升用户体验 │
│ ✅ 数据与展示分离,现代前端架构基础 │
│ ✅ 虽然名字有 XML,但现在多用 JSON 格式 │
└─────────────────────────────────────────────────────────┘
📌 二、AJAX 请求完整流程(5 步走)
🎯 标准操作流程
javascript
// 第 1 步:创建 XMLHttpRequest 对象
const xhr = new XMLHttpRequest();
// 第 2 步:打开请求(配置请求信息)
xhr.open('GET', 'https://api.github.com/orgs/lemoncode/members', true);
// 第 3 步:发送请求
xhr.send();
// 第 4 步:监听状态变化
xhr.onreadystatechange = function() {
// 第 5 步:处理响应
if (xhr.status === 200 && xhr.readyState === 4) {
const data = JSON.parse(xhr.responseText);
console.log(data);
}
};
📊 流程图示意
scss
创建 XHR 对象 → open() 配置 → send() 发送 → 监听 onreadystatechange → 处理响应
↓ ↓ ↓ ↓ ↓
readyState 0 readyState 1 readyState 2 readyState 3-4 数据渲染
📌 三、readyState 5 个状态详解(面试必考)
| 状态值 | 状态名称 | 含义说明 | 触发时机 |
|---|---|---|---|
| 0 | UNSENT | 未初始化 | 创建 XHR 对象后,调用 open() 之前 |
| 1 | OPENED | 已打开 | open() 方法调用完成后 |
| 2 | HEADERS_RECEIVED | 已接收响应头 | send() 后,接收到响应头信息 |
| 3 | LOADING | 加载中 | 正在接收响应体数据 |
| 4 | DONE | 完成 | 响应数据接收完毕 |
🔍 状态变化实战演示
javascript
const xhr = new XMLHttpRequest();
console.log('初始状态:', xhr.readyState); // 0
xhr.open('GET', 'https://api.github.com/orgs/lemoncode/members', true);
console.log('open 后:', xhr.readyState); // 1
xhr.onreadystatechange = function() {
console.log('状态变化:', xhr.readyState, '状态码:', xhr.status);
};
xhr.send();
console.log('send 后:', xhr.readyState); // 1 或 2(异步情况下)
⚠️ 关于 status 的重要说明
javascript
// ❌ 常见误区:在 send() 后立即获取 status
const xhr = new XMLHttpRequest();
xhr.open('GET', 'url', true);
console.log(xhr.status); // 0!请求还未完成,status 为 0
xhr.send();
console.log(xhr.status); // 0!异步请求,代码继续执行
// ✅ 正确做法:在 onreadystatechange 回调中获取
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
console.log(xhr.status); // 200/404/500 等真实状态码
}
};
📌 四、async true vs false 核心区别(重点!)
📝 参数说明
javascript
xhr.open(method, url, async);
// method: 请求方式 (GET/POST...)
// url: 接口地址
// async: true(异步) / false(同步),默认为 true
🔄 异步请求 (async = true)
javascript
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.github.com/orgs/lemoncode/members', true); // 异步
xhr.send();
console.log('第 1 行'); // 立即执行
console.log('第 2 行'); // 立即执行
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log('请求完成,处理数据'); // 稍后执行
}
};
console.log('第 3 行'); // 立即执行,不会等待请求完成
执行顺序:第 1 行 → 第 2 行 → 第 3 行 → 请求完成回调
⏸️ 同步请求 (async = false)
javascript
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.github.com/orgs/lemoncode/members', false); // 同步
xhr.send(); // ⚠️ 页面会阻塞,直到请求完成
console.log('第 1 行'); // 等待请求完成后才执行
console.log('第 2 行'); // 等待请求完成后才执行
console.log('第 3 行'); // 等待请求完成后才执行
console.log(xhr.responseText); // ✅ 可以直接获取响应数据
执行顺序:send() 阻塞 → 请求完成 → 第 1 行 → 第 2 行 → 第 3 行
📊 对比表格
| 特性 | async: true (异步) | async: false (同步) |
|---|---|---|
| 页面阻塞 | ❌ 不阻塞 | ✅ 阻塞,页面冻结 |
| 用户体验 | ✅ 流畅 | ❌ 卡顿,可能无响应 |
| 代码执行 | 继续执行后续代码 | 等待请求完成 |
| 数据获取 | 需在回调中获取 | 可直接获取 |
| 浏览器支持 | ✅ 全部支持 | ⚠️ 部分浏览器已废弃 |
| 推荐使用 | ✅ 强烈推荐 | ❌ 不推荐 |
🎯 执行时序对比图
swift
┌──────────────────────────────────────────────────────────────────┐
│ async: true (异步) │
├──────────────────────────────────────────────────────────────────┤
│ open() → send() → 继续执行 → 继续执行 → 请求返回 → 回调执行 │
│ ↓ │
│ └──── 主线程不阻塞,页面可交互 │
└──────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────┐
│ async: false (同步) │
├──────────────────────────────────────────────────────────────────┤
│ open() → send() → 【阻塞等待】→ 请求返回 → 继续执行 → 继续执行 │
│ ↓ │
│ └──── 主线程阻塞,页面无法交互(冻结) │
└──────────────────────────────────────────────────────────────────┘
📌 五、完整实战案例
🌟 案例:获取 GitHub 组织成员并展示
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>AJAX 获取 GitHub 成员</title>
<style>
#members { list-style: none; padding: 0; }
#members li { padding: 8px; border-bottom: 1px solid #eee; }
.loading { color: #666; }
.error { color: red; }
</style>
</head>
<body>
<h1>GitHub 组织成员列表</h1>
<ul id="members"><li class="loading">加载中...</li></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 data = JSON.parse(xhr.responseText);
document.getElementById('members').innerHTML =
data.map(item => `<li>👤 ${item.login}</li>`).join('');
} else {
document.getElementById('members').innerHTML =
`<li class="error">请求失败,状态码:${xhr.status}</li>`;
}
}
};
xhr.onerror = function() {
document.getElementById('members').innerHTML =
'<li class="error">网络错误</li>';
};
xhr.send();
</script>
</body>
</html>
📌 六、大厂面试高频考点
❓ 考点 1:AJAX 请求的 5 个 readyState 状态?
答案:0-未初始化,1-已打开,2-已接收响应头,3-加载中,4-完成
❓ 考点 2:async true 和 false 的区别?
arduino
答案:
- true:异步,不阻塞页面,推荐使用
- false:同步,阻塞页面,已不推荐使用
❓ 考点 3:为什么现代开发不推荐使用同步 AJAX?
markdown
答案:
1. 阻塞主线程,页面冻结,用户体验差
2. 可能导致浏览器无响应警告
3. 现代浏览器已逐步废弃同步 XHR 支持
4. 有更好替代方案:Promise、async/await
❓ 考点 4:如何正确处理 AJAX 响应数据?
javascript
// ✅ 正确做法
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
JSON.parse(xhr.responseText);
}
}
};
// ❌ 错误做法
xhr.send();
const data = xhr.responseText; // 异步情况下,此时数据还未返回!
📌 七、最佳实践建议
✅ 推荐做法
javascript
// 1. 始终使用异步请求 (async: true)
xhr.open('GET', url, true);
// 2. 同时检查 readyState 和 status
if (xhr.readyState === 4 && xhr.status === 200) { }
// 3. 添加错误处理
xhr.onerror = function() {
console.error('网络错误');
};
// 4. 设置请求超时
xhr.timeout = 5000;
xhr.ontimeout = function() {
console.error('请求超时');
};
❌ 避免做法
javascript
// 1. 避免使用同步请求
xhr.open('GET', url, false); // ❌
// 2. 避免在 send() 后立即使用响应数据
xhr.send();
console.log(xhr.responseText); // ❌ 数据可能还未返回
// 3. 避免只检查 status 不检查 readyState
if (xhr.status === 200) { } // ❌ 不完整
📌 八、现代替代方案
虽然 XMLHttpRequest 仍在使用,但现代开发更推荐使用:
| 方案 | 特点 | 推荐度 |
|---|---|---|
| Fetch API | 原生 Promise,语法简洁 | ⭐⭐⭐⭐⭐ |
| Axios | 功能强大,拦截器支持 | ⭐⭐⭐⭐⭐ |
| async/await | 异步代码同步写法 | ⭐⭐⭐⭐⭐ |
javascript
// Fetch API 示例(现代推荐)
async function getMembers() {
try {
const response = await fetch('https://api.github.com/orgs/lemoncode/members');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('请求失败:', error);
}
}
📝 总结
| 知识点 | 核心要点 |
|---|---|
| AJAX 流程 | 创建 → open → send → 监听 → 处理 |
| readyState | 0→1→2→3→4,只有 4 表示完成 |
| async true | 异步,不阻塞,推荐使用 |
| async false | 同步,阻塞页面,不推荐 |
| 状态判断 | readyState === 4 && status === 200 |
| 数据获取 | 必须在回调函数中获取响应数据 |
💡 学习建议:AJAX 是前端基础中的基础,建议动手敲一遍代码,观察控制台输出,理解异步执行流程。掌握后可进一步学习 Fetch API 和 Axios。
👍 觉得有用请点赞收藏,有问题欢迎评论区交流!
本文同步发布于稀土掘金,转载请注明出处