🔥 前端必考!AJAX 数据请求全解析,async true/false 区别一次搞懂

🔥 前端必考!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。
👍 觉得有用请点赞收藏,有问题欢迎评论区交流!


本文同步发布于稀土掘金,转载请注明出处

相关推荐
烤麻辣烫1 小时前
正则表达式快速掌握
前端·javascript·学习·正则表达式·html
心之语歌2 小时前
flutter 父子组件互相调用方法,值更新
前端·javascript·flutter
肖。35487870943 小时前
html中onclick误区,后续变量会更改怎么办?
android·java·javascript·css·html
Lee川3 小时前
从字符串操作到数组映射:一次JavaScript数据处理的深度探索
javascript
随逸1773 小时前
《React 性能优化:useMemo 与 useCallback 实战》
javascript·react.js
HelloReader3 小时前
Tauri 用“系统 WebView + 原生能力”构建更小更快的跨平台应用
前端·javascript·后端
滕青山3 小时前
JSON转TypeScript接口核心JS实现
前端·javascript·vue.js
Xin_z_4 小时前
Vue3 + Element Plus el-tree 节点点击选中问题修复总结
前端·javascript·vue.js
linux_cfan4 小时前
从“线性观看”到“语义检索”:企业级视频知识库播放器选型指南 (2026版)
javascript·学习·音视频·html5