你知道什么是 Ajax 吗?------ 从入门到原理,一篇彻底搞懂
面试官:"你知道什么是 Ajax 吗?"
你:"......好像是用 JavaScript 发请求,不刷新页面就能更新数据......"
面试官:"那你能说说它的工作原理和优缺点吗?"
你:"emmm..."
如果你对 Ajax 的理解还停留在 "异步请求" 四个字,那这篇文章就是为你准备的。本文将从 Ajax 的诞生背景、核心概念、工作流程、底层原理(XMLHttpRequest)、代码示例、优缺点,再到现代替代方案(Fetch API、Axios),带你全方位掌握 Ajax。
一、为什么需要 Ajax?------ 传统 Web 的痛点
在 Ajax 出现之前(约 2005 年之前),Web 应用采用 同步交互模式:
- 用户在表单填写数据,点击提交。
- 浏览器将整个页面数据发送给服务器。
- 服务器处理完成后,返回一个 完整的新页面。
- 浏览器重新加载整个页面。
这种模式的缺点非常明显:
- 体验差:哪怕只改一个数据,也要刷新整个页面,出现白屏等待。
- 带宽浪费:传输大量重复的 HTML 结构。
- 交互不连贯:例如填写表单时校验用户名是否可用,必须提交整个页面后才能知道结果。
Ajax 的出现,让 Web 应用从"页面集"进化为"单页应用(SPA)",开启了 Web 2.0 时代。
二、Ajax 的定义与全称
Ajax = Asynchronous JavaScript and XML(异步的 JavaScript 与 XML 技术)。
注意:虽然名字里有 XML,但现在的 Ajax 通信绝大多数使用 JSON 格式,XML 已经很少见了。
Ajax 不是一种编程语言 ,也不是一个框架,而是一套 现有的 Web 技术的组合 ,用于在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页内容。
三、Ajax 的核心技术组成
Ajax
HTML/CSS
DOM
JavaScript
XMLHttpRequest
核心对象
XML/JSON
数据格式
| 技术组件 | 作用 |
|---|---|
| HTML/CSS | 呈现页面结构与样式 |
| DOM | 动态更新页面局部内容 |
| JavaScript | 驱动业务逻辑,发起请求、处理响应 |
| XMLHttpRequest | Ajax 的核心------浏览器内置对象,用于与服务器异步通信 |
| XML / JSON | 数据传输格式(现代普遍使用 JSON) |
四、Ajax 的工作流程(附流程图)
服务器 浏览器(JS) 用户 服务器 浏览器(JS) 用户 用户可继续操作页面(无阻塞) 触发事件(点击、输入等) 创建 XMLHttpRequest 对象 发送异步请求(不刷新页面) 返回数据(XML/JSON/文本) 解析数据,更新 DOM 页面局部刷新,用户看到新内容
详细步骤解释:
- 触发事件:用户在页面上执行某个操作(点击按钮、输入框失焦等)。
- 创建 XMLHttpRequest 对象 :JS 代码实例化
XMLHttpRequest(或ActiveXObject兼容老 IE)。 - 初始化请求 :调用
open(method, url, async),指定请求方式、地址、是否异步(通常为 true)。 - 设置回调函数 :监听
onreadystatechange事件,当readyState === 4且status === 200时处理响应数据。 - 发送请求 :调用
send(body),如果是 GET 请求 body 可为 null。 - 服务器处理:接收请求,执行业务逻辑,返回数据(JSON/XML/文本)。
- 接收响应:浏览器回调函数接收到数据。
- 更新 DOM:使用 JS 操作 DOM 元素,更新页面局部内容。
五、原生 Ajax 代码示例(GET 请求)
javascript
// 1. 创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();
// 2. 配置请求
xhr.open('GET', 'https://api.example.com/users?id=123', true);
// 3. 监听状态变化
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) { // 请求完成
if (xhr.status === 200) { // HTTP 成功
var data = JSON.parse(xhr.responseText);
console.log(data);
// 更新页面 DOM
document.getElementById('userName').innerText = data.name;
} else {
console.error('请求失败:', xhr.status);
}
}
};
// 4. 发送请求
xhr.send();
POST 请求(带 JSON 数据)
javascript
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/users', true);
xhr.setRequestHeader('Content-Type', 'application/json'); // 设置请求头
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 201) {
console.log('创建成功', JSON.parse(xhr.responseText));
}
};
var payload = JSON.stringify({ name: '张三', age: 25 });
xhr.send(payload);
六、XMLHttpRequest 的关键属性与方法
| 属性/方法 | 说明 |
|---|---|
readyState |
0: UNSENT(未初始化);1: OPENED(已调用open);2: HEADERS_RECEIVED;3: LOADING(下载中);4: DONE(完成) |
status |
HTTP 状态码(200, 404, 500 等) |
statusText |
状态文本("OK", "Not Found" 等) |
responseText |
响应体(字符串形式) |
responseXML |
响应体(XML 格式,已解析为 Document 对象) |
onreadystatechange |
状态改变时的回调函数 |
open(method, url, async) |
初始化请求 |
send(data) |
发送请求,data 可选(POST 时使用) |
setRequestHeader(header, value) |
设置请求头(必须在 open 之后、send 之前) |
abort() |
终止请求 |
七、Ajax 的优点与缺点
✅ 优点
- 无刷新更新:只更新局部数据,用户体验流畅。
- 异步通信:请求期间用户可与其他页面元素交互,不阻塞。
- 减少带宽消耗:只传输必要的数据,而不是整个页面。
- 标准化支持 :所有现代浏览器都支持
XMLHttpRequest。 - 前后端分离:为 RESTful API 和 SPA 奠定基础。
❌ 缺点
- 破坏浏览器后退/前进机制 :因为页面未整体刷新,浏览器不会自动记录 Ajax 操作状态。解决方案:使用
pushState+replaceState(HTML5 History API)。 - SEO 不友好:搜索引擎爬虫通常不会执行 JavaScript,因此 Ajax 加载的内容可能无法被索引。解决方案:服务端渲染(SSR)或预渲染。
- 跨域问题:默认受同源策略限制(协议、域名、端口必须一致)。解决方案:CORS、JSONP(仅限 GET)、代理转发。
- 增加代码复杂度:需要处理请求状态、错误、竞争条件(如异步顺序)。
- 安全问题:可能暴露 API 端点,增加 XSS、CSRF 风险。
八、Ajax 的进化:Fetch API 与 Axios
随着现代前端发展,XMLHttpRequest 的写法已略显繁琐。现在更推荐使用 Fetch API 或 Axios。
8.1 Fetch API(浏览器原生,基于 Promise)
javascript
// GET 请求
fetch('https://api.example.com/users?id=123')
.then(response => {
if (!response.ok) throw new Error('HTTP error ' + response.status);
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error(error));
// POST 请求
fetch('https://api.example.com/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: '李四', age: 30 })
})
.then(res => res.json())
.then(data => console.log(data));
Fetch 的优点:
- 基于 Promise,避免回调地狱。
- 语法更简洁。
- 支持 Service Worker 和流式处理。
Fetch 的注意点:
- 默认 不会 在 HTTP 错误状态(如 404、500)时 reject,需要手动判断
response.ok。 - 默认 不发送 cookies ,需要添加
credentials: 'include'。
8.2 Axios(第三方库,功能更强大)
javascript
// GET
axios.get('/users', { params: { id: 123 } })
.then(res => console.log(res.data))
.catch(err => console.error(err));
// POST
axios.post('/users', { name: '王五', age: 28 })
.then(res => console.log(res.data));
Axios 优势:
- 自动转换 JSON 数据。
- 请求/响应拦截器。
- 支持取消请求、超时设置。
- 在浏览器和 Node.js 环境通用。
- 内置 XSRF 保护。
九、Ajax 与 Fetch、Axios 的关系
Ajax 技术概念
底层API: XMLHttpRequest
现代替代方案
Fetch API
浏览器原生,Promise风格
Axios
第三方库,功能最全
手动管理状态、回调
简洁但需处理边缘情况
开箱即用,适合复杂项目
结论 :Ajax 是一个 技术思想 ,
XMLHttpRequest是其经典实现;Fetch和Axios是更现代的演进版本。
十、常见面试题解析
1. Ajax 与 Fetch 有什么区别?
| 对比项 | Ajax (XMLHttpRequest) | Fetch |
|---|---|---|
| 异步处理 | 回调函数 / onreadystatechange | Promise |
| 语法复杂度 | 较复杂 | 简洁 |
| 错误处理 | 需要判断 status | 只网络错误 reject,HTTP 错误需手动 |
| 默认携带 Cookie | 是 | 否(需 credentials: 'include') |
| 请求取消 | 支持 abort() | 需借助 AbortController |
| 进度监听 | 支持(上传/下载进度) | 不支持(但可配合 Streams) |
2. jQuery 的 $.ajax 与原生 Ajax 是什么关系?
$.ajax 是 jQuery 对原生 XMLHttpRequest 的封装,提供了更友好的 API、自动数据转换、跨域支持(JSONP)等。随着现代框架(React/Vue)和 Fetch API 的普及,jQuery 的 Ajax 已不再是首选。
3. 如何用 Ajax 实现文件上传?
使用 FormData 对象:
javascript
var formData = new FormData();
formData.append('file', fileInput.files[0]);
var xhr = new XMLHttpRequest();
xhr.open('POST', '/upload', true);
xhr.send(formData);
4. Ajax 请求如何设置超时?
javascript
xhr.timeout = 3000; // 3秒超时
xhr.ontimeout = function() {
console.error('请求超时');
};
十一、总结
| 知识点 | 核心内容 |
|---|---|
| 定义 | 异步 JavaScript 与 XML,一套在无刷新下与服务器交换数据的技术组合 |
| 核心对象 | XMLHttpRequest |
| 工作流程 | 创建对象 → open → 设置回调 → send → 收到响应 → 更新 DOM |
| 优点 | 刷新体验好、异步不阻塞、减少带宽、前后端分离 |
| 缺点 | 破坏浏览器历史、SEO 不友好、跨域限制、代码复杂度上升 |
| 现代替代 | Fetch API、Axios |
Ajax 是 Web 前端发展史中里程碑式的技术。理解它的原理,不仅能帮你应对面试,更能让你在设计 API 交互时做出合理的技术选型。现在,你能自信地回答 "你知道什么是 Ajax 吗?" 了吧?
🌟 思考题:假设你需要实现一个实时搜索输入框,用户每输入一个字符就向服务器请求搜索结果。如果用户输入速度很快,会发送大量请求,如何避免过载和错序响应?欢迎在评论区交流你的方案。