一、AJAX 核心概念
AJAX (Asynchronous JavaScript and XML) 是一种无需重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。
核心特点:
- 异步通信:不阻塞用户操作
- 局部更新:仅刷新页面部分内容
- 数据格式:现代主要用 JSON,早期用 XML
- 跨平台:基于标准 JavaScript 和 XMLHttpRequest
二、原生 AJAX 实现流程
1. 创建 XMLHttpRequest 对象
javascript
const xhr = new XMLHttpRequest();
2. 配置请求
javascript
xhr.open('GET', 'https://api.example.com/data', true); // 异步请求
3. 设置回调函数
javascript
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
console.log(JSON.parse(xhr.responseText));
} else {
console.error('请求失败:', xhr.statusText);
}
};
xhr.onerror = function() {
console.error('网络错误');
};
4. 发送请求
javascript
xhr.send();
5. 带 POST 数据的示例
javascript
xhr.open('POST', '/api/submit');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({ name: 'Alice' }));
三、Fetch API(现代替代方案)
javascript
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) throw new Error('Network error');
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
对比 XMLHttpRequest:
特性 | Fetch API | XMLHttpRequest |
---|---|---|
链式调用 | ✅ Promise-based | ❌ 回调嵌套 |
默认不带Cookie | ✅ 需配置 credentials | ✅ 默认携带 |
取消请求 | ❌ 需 AbortController | ✅ xhr.abort() |
四、高频问题
1、基础篇
Q: AJAX 的全称是什么?核心作用?
Asynchronous JavaScript And XML,实现异步数据加载和局部更新。
Q: XMLHttpRequest 的 readyState 有哪几种状态?
0: 未初始化
1: 已打开连接
2: 已接收响应头
3: 下载响应体中
4: 请求完成
Q: 如何解决 AJAX 的跨域问题?
CORS (服务端设置 Access-Control-Allow-Origin)
JSONP (仅限 GET)
代理服务器 (Nginx 反向代理)
2、进阶篇
Q: Fetch 和 AJAX 的主要区别?
Fetch 基于 Promise,XHR 基于事件
Fetch 需要手动处理错误(不会 reject HTTP 错误状态码)
Fetch 默认不发送/接收 Cookies
Q: 如何取消一个 AJAX 请求?
javascript
// XHR
const xhr = new XMLHttpRequest();
xhr.abort(); // 取消
// Fetch
const controller = new AbortController();
fetch(url, { signal: controller.signal });
controller.abort(); // 取消
Q: 什么是 AJAX 的 CSRF 攻击?如何防御?
攻击原理:利用用户已登录状态伪造请求
防御措施:
同源检测
CSRF Token
SameSite Cookie
3、原理篇
Q: 手写一个简易的 AJAX 封装函数
javascript
function myAjax({ method = 'GET', url, data, headers }) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open(method, url);
for (const key in headers) {
xhr.setRequestHeader(key, headers[key]);
}
xhr.onload = () => resolve(JSON.parse(xhr.responseText));
xhr.onerror = () => reject(xhr.statusText);
xhr.send(JSON.stringify(data));
});
}
Q: 解释 AJAX 的长轮询(Long Polling)与 WebSocket 的区别
长轮询:客户端发起请求,服务器保持连接直到有数据返回
WebSocket:全双工通信,服务端可主动推送
五、实际应用场景
1. 表单提交无刷新
javascript
document.getElementById('myForm').addEventListener('submit', function(e) {
e.preventDefault();
fetch('/submit', {
method: 'POST',
body: new FormData(this)
}).then(/* 处理响应 */);
});
2. 无限滚动加载
javascript
window.addEventListener('scroll', function() {
if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 500) {
fetch('/more-items').then(/* 追加内容 */);
}
});
六、调试与优化技巧
查看 AJAX 请求
Chrome 开发者工具 → Network 面板
过滤 XHR/Fetch 请求
性能优化
合并请求(如 GraphQL)
缓存响应结果
javascript
const cachedData = localStorage.getItem('apiData');
if (cachedData) {
render(JSON.parse(cachedData));
} else {
fetch('/data').then(data => {
localStorage.setItem('apiData', JSON.stringify(data));
render(data);
});
}
七、实战题
题目:实现一个带重试机制的 AJAX 请求函数
javascript
function fetchWithRetry(url, maxRetries = 3, delay = 1000) {
return new Promise((resolve, reject) => {
const attempt = (retryCount) => {
fetch(url)
.then(resolve)
.catch(error => {
if (retryCount >= maxRetries) return reject(error);
setTimeout(() => attempt(retryCount + 1), delay);
});
};
attempt(0);
});
}
八、现代替代技术
技术 | 特点 | 适用场景 |
---|---|---|
GraphQL | 单请求获取多资源 | 复杂数据关联查询 |
WebSocket | 全双工实时通信 | 聊天室、股票行情 |
Server-Sent Events | 服务端单向推送 | 实时通知(如新闻推送) |