AJAX 解析与高频问题
一、AJAX 核心概念
AJAX (Asynchronous JavaScript and XML) 是一种无需重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。
核心特点:
- 异步通信:不阻塞用户操作
- 局部更新:仅刷新页面部分内容
- 数据格式:现代主要用 JSON,早期用 XML
- 跨平台:基于标准 JavaScript 和 XMLHttpRequest
二、原生 AJAX 实现流程
1. 创建 XMLHttpRequest 对象
const xhr = new XMLHttpRequest();
2. 配置请求
xhr.open('GET', 'https://api.example.com/data', true); // 异步请求
3. 设置回调函数
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. 发送请求
xhr.send();
5. 带 POST 数据的示例
xhr.open('POST', '/api/submit');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({ name: 'Alice' }));
三、Fetch API(现代替代方案)
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 默认不发送/接收 CookiesQ: 如何取消一个 AJAX 请求?
// XHR
const xhr = new XMLHttpRequest();
xhr.abort(); // 取消// Fetch
const controller = new AbortController();
fetch(url, { signal: controller.signal });
controller.abort(); // 取消
Q: 什么是 AJAX 的 CSRF 攻击?如何防御?攻击原理:利用用户已登录状态伪造请求防御措施:同源检测CSRF TokenSameSite Cookie
3、原理篇
Q: 手写一个简易的 AJAX 封装函数
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. 表单提交无刷新
document.getElementById('myForm').addEventListener('submit', function(e) {e.preventDefault();fetch('/submit', {method: 'POST',body: new FormData(this)}).then(/* 处理响应 */);
});
2. 无限滚动加载
window.addEventListener('scroll', function() {if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 500) {fetch('/more-items').then(/* 追加内容 */);}
});
六、调试与优化技巧
查看 AJAX 请求Chrome 开发者工具 → Network 面板过滤 XHR/Fetch 请求性能优化合并请求(如 GraphQL)缓存响应结果
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 请求函数
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 | 服务端单向推送 | 实时通知(如新闻推送) |