文章目录
- [AJAX 使用说明](#AJAX 使用说明)
-
- [一、AJAX 简介](#一、AJAX 简介)
- [二、AJAX 工作原理](#二、AJAX 工作原理)
- [三、AJAX 核心 API](#三、AJAX 核心 API)
-
- [1. 创建 XMLHttpRequest 对象](#1. 创建 XMLHttpRequest 对象)
- [2. Fetch API(现代替代方案)](#2. Fetch API(现代替代方案))
- [四、XMLHttpRequest 完整使用示例](#四、XMLHttpRequest 完整使用示例)
- [五、AJAX 请求状态 (readyState)](#五、AJAX 请求状态 (readyState))
- 六、常用请求方法示例
-
- [1. GET 请求(获取数据)](#1. GET 请求(获取数据))
- [2. POST 请求(提交数据)](#2. POST 请求(提交数据))
- [七、Fetch API 使用示例](#七、Fetch API 使用示例)
- 八、错误处理与超时控制
- 九、最佳实践
- 十、完整示例:用户搜索功能
- 总结
AJAX 使用说明
一、AJAX 简介
AJAX(Asynchronous JavaScript and XML)是一种在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页内容的技术。
主要特点:
- 异步通信:后台与服务器交换数据,不阻塞用户界面
- 局部更新:只更新网页的某一部分,无需刷新整个页面
- 多种数据格式:支持 XML、JSON、HTML、文本等
二、AJAX 工作原理
用户 浏览器 XMLHttpRequest 服务器 触发事件(点击/输入等) 创建XHR对象 发送异步请求 处理请求 查询数据库/执行操作 返回响应数据 触发回调函数 更新页面局部内容 用户 浏览器 XMLHttpRequest 服务器
三、AJAX 核心 API
1. 创建 XMLHttpRequest 对象
// 现代浏览器
const xhr = new XMLHttpRequest();
// 兼容旧版IE (IE6及以下)
if (window.ActiveXObject) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
2. Fetch API(现代替代方案)
javascript
fetch(url, options)
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
四、XMLHttpRequest 完整使用示例
javascript
// 1. 创建XHR对象
const xhr = new XMLHttpRequest();
// 2. 配置请求
xhr.open('GET', 'https://api.example.com/data', true); // true表示异步
// 3. 设置请求头(可选)
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer token123');
// 4. 定义响应处理函数
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) { // 请求完成
if (xhr.status === 200) { // 成功响应
const data = JSON.parse(xhr.responseText);
console.log('成功:', data);
updateUI(data);
} else {
console.error('请求失败:', xhr.status, xhr.statusText);
handleError(xhr.status);
}
}
};
// 5. 处理加载进度(可选)
xhr.onprogress = function(event) {
if (event.lengthComputable) {
const percentComplete = (event.loaded / event.total) * 100;
console.log(`加载进度: ${percentComplete}%`);
}
};
// 6. 处理错误(可选)
xhr.onerror = function() {
console.error('网络请求错误');
};
// 7. 发送请求
xhr.send();
// 对于POST请求,需要传递数据
// xhr.send(JSON.stringify({key: 'value'}));
五、AJAX 请求状态 (readyState)
0: UNSENT 1: OPENED 2: HEADERS_RECEIVED 3: LOADING 4: DONE
状态说明:
- 0 (UNSENT):XHR对象已创建,但open()未调用
- 1 (OPENED):open()已调用,但send()未调用
- 2 (HEADERS_RECEIVED):send()已调用,响应头已接收
- 3 (LOADING):响应体正在下载中
- 4 (DONE):请求完成,响应就绪
六、常用请求方法示例
1. GET 请求(获取数据)
javascript
function getData(url, callback) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function() {
if (xhr.status === 200) {
callback(null, JSON.parse(xhr.responseText));
} else {
callback(new Error(`请求失败: ${xhr.status}`));
}
};
xhr.onerror = function() {
callback(new Error('网络错误'));
};
xhr.send();
}
2. POST 请求(提交数据)
javascript
function postData(url, data, callback) {
const xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
callback(null, JSON.parse(xhr.responseText));
} else {
callback(new Error(`请求失败: ${xhr.status}`));
}
};
xhr.onerror = function() {
callback(new Error('网络错误'));
};
xhr.send(JSON.stringify(data));
}
七、Fetch API 使用示例
javascript
// GET 请求
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error('网络响应异常');
}
return response.json();
})
.then(data => {
console.log('数据:', data);
})
.catch(error => {
console.error('错误:', error);
});
// POST 请求
fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'John',
age: 30
})
})
.then(response => response.json())
.then(data => console.log('成功:', data))
.catch(error => console.error('错误:', error));
八、错误处理与超时控制
javascript
// 超时设置
xhr.timeout = 10000; // 10秒超时
xhr.ontimeout = function() {
console.error('请求超时');
};
// 使用Promise封装AJAX
function ajaxPromise(method, url, data = null) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open(method, url, true);
if (data && method === 'POST') {
xhr.setRequestHeader('Content-Type', 'application/json');
}
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.responseText));
} else {
reject(new Error(`HTTP ${xhr.status}: ${xhr.statusText}`));
}
};
xhr.onerror = function() {
reject(new Error('网络请求失败'));
};
xhr.ontimeout = function() {
reject(new Error('请求超时'));
};
xhr.send(data ? JSON.stringify(data) : null);
});
}
// 使用示例
ajaxPromise('GET', 'https://api.example.com/data')
.then(data => console.log(data))
.catch(error => console.error(error));
九、最佳实践
- 添加加载指示器:在请求期间显示加载状态
- 防抖/节流:避免频繁请求,特别是在搜索框中
- 错误友好提示:给用户清晰的错误反馈
- 取消请求:必要时取消未完成的请求
- 安全考虑 :
- 验证和清理用户输入
- 使用HTTPS
- 实施CORS策略
- 防止CSRF攻击
十、完整示例:用户搜索功能
html
<!DOCTYPE html>
<html>
<head>
<style>
#loading { display: none; color: blue; }
.error { color: red; }
.user-item { padding: 5px; border-bottom: 1px solid #ccc; }
</style>
</head>
<body>
<input type="text" id="searchInput" placeholder="搜索用户...">
<div id="loading">加载中...</div>
<div id="results"></div>
<div id="error" class="error"></div>
<script>
let currentRequest = null;
let searchTimeout = null;
document.getElementById('searchInput').addEventListener('input', function(e) {
const query = e.target.value.trim();
// 清除之前的超时
clearTimeout(searchTimeout);
if (query.length < 2) {
document.getElementById('results').innerHTML = '';
return;
}
// 显示加载指示器
document.getElementById('loading').style.display = 'block';
document.getElementById('error').innerHTML = '';
// 防抖:延迟500ms执行搜索
searchTimeout = setTimeout(() => {
searchUsers(query);
}, 500);
});
function searchUsers(query) {
// 取消之前的请求
if (currentRequest) {
currentRequest.abort();
}
// 创建新请求
const xhr = new XMLHttpRequest();
currentRequest = xhr;
xhr.open('GET', `https://api.example.com/users?q=${encodeURIComponent(query)}`, true);
xhr.onload = function() {
document.getElementById('loading').style.display = 'none';
if (xhr.status === 200) {
const users = JSON.parse(xhr.responseText);
displayResults(users);
} else {
document.getElementById('error').innerHTML = '搜索失败,请重试';
}
currentRequest = null;
};
xhr.onerror = function() {
document.getElementById('loading').style.display = 'none';
document.getElementById('error').innerHTML = '网络连接错误';
currentRequest = null;
};
xhr.send();
}
function displayResults(users) {
const resultsDiv = document.getElementById('results');
if (users.length === 0) {
resultsDiv.innerHTML = '<p>未找到用户</p>';
return;
}
resultsDiv.innerHTML = users.map(user =>
`<div class="user-item">${user.name} - ${user.email}</div>`
).join('');
}
</script>
</body>
</html>
总结
AJAX 是现代Web应用的核心技术之一,它使得网页能够实现更流畅的用户体验。虽然现在有更现代的 Fetch API 和基于 Promise 的解决方案,但理解传统的 XMLHttpRequest 工作原理仍然很重要,因为:
- 兼容性:某些旧项目仍在使用
- 进度监控:XHR 支持上传/下载进度跟踪
- 基础知识:理解底层机制有助于使用更高级的库(如 Axios)
根据项目需求,可以选择:
- 原生 XHR:需要精细控制或兼容旧浏览器时
- Fetch API:现代浏览器,需要简洁语法时
- Axios 等库:需要拦截器、取消请求等高级功能时