🌐在现代 Web 开发中,Ajax(Asynchronous JavaScript and XML) 是实现网页局部刷新、提升用户体验的核心技术之一。尽管名字中含有 “XML”,但如今它更多用于处理 JSON 格式的数据。本文将深入剖析 Ajax 的工作原理、完整流程、关键属性与方法,并提供手写 Ajax 请求的详细示例,帮助你彻底掌握这一前端必备技能。
⚙️ 什么是 Ajax?
Ajax 全称是 Asynchronous JavaScript and XML,但它并不局限于 XML——如今绝大多数 Ajax 请求都使用 JSON(JavaScript Object Notation) 作为数据交换格式,因其更轻量、更易解析。
Ajax 的核心思想是:在不重新加载整个页面的情况下,通过 JavaScript 向服务器发送请求并接收响应,从而动态更新页面内容。这种“异步”通信机制极大地提升了 Web 应用的交互性和性能。
🔁 Ajax 的基本工作流程
要使用原生 JavaScript 实现一个完整的 Ajax 请求,需遵循以下标准流程:
1. 🧱 实例化 XMLHttpRequest 对象
const xhr = new XMLHttpRequest();
XMLHttpRequest 是浏览器内置的构造函数,用于创建一个 Ajax 请求对象。这是所有操作的起点。
💡 注意:虽然名字叫
XMLHttpRequest,但它完全可以处理 JSON、文本、HTML 等多种格式。
2. 🔓 调用 open() 方法配置请求
xhr.open(method, url, async);
method:HTTP 请求方法,如'GET'、'POST'、'PUT'、'DELETE'等。url:请求的目标地址(可以是相对路径或绝对 URL)。async:是否异步执行,默认为true(强烈建议保持异步,避免阻塞 UI)。
例如:
xhr.open('GET', '/api/users', true);
3. 📤 调用 send() 方法发送请求
xhr.send(body);
- 对于 GET 请求,通常传入
null或省略参数,因为数据通过 URL 传递。 - 对于 POST/PUT 请求,可在此处传入请求体(如 JSON 字符串、表单数据等)。
示例(POST):
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({ name: 'Alice', age: 25 }));
⚠️ 注意:若需发送 JSON 数据,务必设置正确的
Content-Type请求头。
4. 👂 监听请求状态变化:onreadystatechange
Ajax 是异步的,因此不能直接获取响应结果。我们需要监听 readyState 的变化:
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
// 请求成功完成
const data = JSON.parse(xhr.responseText);
console.log(data);
}
};
✅ 关键判断条件:
readyState === 4:请求已完成(详见下文状态码说明)status === 200:HTTP 状态码为 200,表示成功
📊 readyState 状态详解
XMLHttpRequest 对象的 readyState 属性表示当前请求的阶段,共有 5 个值:
| 值 | 状态 | 说明 |
|---|---|---|
| 0 | UNSENT | XMLHttpRequest 对象已创建,但尚未调用 open() |
| 1 | OPENED | open() 已被调用,连接已建立 |
| 2 | HEADERS_RECEIVED | send() 已被调用,响应头和状态码已收到 |
| 3 | LOADING | 正在接收响应体(可能部分数据已可用) |
| 4 | DONE | 整个请求过程完成,响应数据全部接收完毕 |
📌 只有当
readyState === 4时,才能安全地读取responseText或response。
📡 HTTP 状态码(status)
xhr.status 返回服务器的 HTTP 状态码,常见值包括:
200:OK,请求成功201:Created,资源创建成功(常用于 POST)400:Bad Request,客户端请求错误401:Unauthorized,未认证403:Forbidden,无权限404:Not Found,资源不存在500:Internal Server Error,服务器内部错误
✅ 判断成功通常用
xhr.status >= 200 && xhr.status < 300更严谨,因为 201、204 等也属于成功。
🧩 解析响应数据:JSON.parse()
服务器返回的数据通常是字符串形式(即使看起来像对象),需手动解析:
const data = JSON.parse(xhr.responseText);
xhr.responseText:以字符串形式返回响应体。- 若服务器返回非 JSON(如纯文本),则无需解析。
⚠️ 如果响应不是合法 JSON,
JSON.parse()会抛出错误!建议加 try-catch:
try {
const data = JSON.parse(xhr.responseText);
} catch (e) {
console.error('JSON 解析失败:', e);
}
✍️ 手写一个完整的 Ajax 函数
结合以上知识,我们可以封装一个通用的 Ajax 函数:
function ajax(options) {
const { method = 'GET', url, data = null, success, error } = options;
const xhr = new XMLHttpRequest();
// 配置请求
xhr.open(method.toUpperCase(), url, true);
// 设置请求头(仅对 POST/PUT 等有 body 的请求)
if (data && typeof data === 'object') {
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));
} else {
xhr.send();
}
// 监听状态变化
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
let response;
try {
response = JSON.parse(xhr.responseText);
} catch (e) {
response = xhr.responseText; // 非 JSON 响应
}
success && success(response);
} else {
error && error(`请求失败: ${xhr.status}`);
}
}
};
}
// 使用示例
ajax({
method: 'POST',
url: '/api/login',
data: { username: 'admin', password: '123456' },
success: (res) => console.log('登录成功', res),
error: (msg) => console.error(msg)
});
🛑 注意事项与最佳实践
- 跨域问题:Ajax 默认受同源策略限制。若需跨域,服务器必须配置 CORS(
Access-Control-Allow-Origin)。 - 安全性:不要在前端暴露敏感接口或密钥;使用 HTTPS 防止中间人攻击。
- 错误处理:除了
status,还应监听onerror事件处理网络错误:xhr.onerror = function() { console.error('网络错误'); }; - 现代替代方案:虽然原生 Ajax 是基础,但实际开发中更推荐使用
fetchAPI 或 Axios,它们基于 Promise,语法更简洁。
🎯 总结
Ajax 是前端与后端通信的基石技术。掌握其核心流程——实例化 → open → send → 监听 onreadystatechange → 判断 readyState 和 status → 解析响应——不仅能应对面试题,更能深入理解 Web 数据交互的本质。
尽管现代框架(如 React、Vue)和工具(如 Axios)简化了网络请求,但手写原生 Ajax 依然是检验前端基本功的重要标准。只有理解底层机制,才能在复杂场景中游刃有余。
✅ 会读 Ajax?不够!
✅ 会手写 Ajax?这才是真功夫!
📚 延伸学习建议:
- 学习
fetchAPI 与 Ajax 的对比 - 了解 WebSocket 与 Ajax 的适用场景差异
- 探索如何用 Ajax 实现文件上传、进度条等功能
现在,你已经拥有了从零实现 Ajax 的全部知识!去动手试试吧!🚀