XMLHttpRequest 是浏览器提供的原生 API,用于在后台与服务器交换数据,是实现 Ajax (Asynchronous JavaScript and XML) 的核心技术。
// 创建 XMLHttpRequest 对象
const xhr = new XMLHttpRequest();
// 配置请求
xhr.open('GET', 'https://api.example.com/data', true); // true 表示异步
// 设置请求头(可选)
xhr.setRequestHeader('Content-Type', 'application/json');
// 处理响应
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
const response = JSON.parse(xhr.responseText);
console.log('成功:', response);
} else {
console.error('错误:', xhr.statusText);
}
};
xhr.onerror = function() {
console.error('请求失败');
};
// 发送请求
xhr.send();
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/data', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
console.log('响应:', JSON.parse(xhr.responseText));
}
};
const data = { name: 'John', age: 30 };
xhr.send(JSON.stringify(data));
优点:
缺点:
jQuery 是一个流行的 JavaScript 库,提供了简化的 Ajax 方法,封装了 XMLHttpRequest 的复杂性。
// GET 请求
$.ajax({
url: 'https://api.example.com/data',
method: 'GET',
dataType: 'json',
success: function(response) {
console.log('成功:', response);
},
error: function(xhr, status, error) {
console.error('错误:', error);
}
});
// 简化的 GET 方法
$.get('https://api.example.com/data', function(response) {
console.log('成功:', response);
});
// POST 请求
$.post('https://api.example.com/data',
{ name: 'John', age: 30 },
function(response) {
console.log('成功:', response);
}
);
$.ajax({
url: 'https://api.example.com/data',
method: 'POST',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify({ name: 'John', age: 30 }),
headers: {
'Authorization': 'Bearer token123'
},
beforeSend: function(xhr) {
console.log('请求发送前');
},
success: function(response, status, xhr) {
console.log('成功:', response);
},
error: function(xhr, status, error) {
console.error('错误:', error);
},
complete: function(xhr, status) {
console.log('请求完成');
}
});
优点:
缺点:
Fetch API 是现代浏览器提供的原生 API,基于 Promise 设计,提供了更强大、更灵活的功能。
// 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);
});
// 使用 async/await
async function getData() {
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error('网络响应不正常');
}
const data = await response.json();
console.log('数据:', data);
} catch (error) {
console.error('错误:', error);
}
}
fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token123'
},
body: JSON.stringify({
name: 'John',
age: 30
})
})
.then(response => response.json())
.then(data => console.log('成功:', data))
.catch(error => console.error('错误:', error));
// 超时处理
function fetchWithTimeout(url, options = {}, timeout = 5000) {
return Promise.race([
fetch(url, options),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('请求超时')), timeout)
)
]);
}
// 发送 FormData
const formData = new FormData();
formData.append('username', 'john');
formData.append('avatar', fileInput.files[0]);
fetch('https://api.example.com/upload', {
method: 'POST',
body: formData
});
// 取消请求(AbortController)
const controller = new AbortController();
const signal = controller.signal;
fetch('https://api.example.com/data', { signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(err => {
if (err.name === 'AbortError') {
console.log('请求被取消');
}
});
// 取消请求
controller.abort();
优点:
缺点:
Axios 是一个基于 Promise 的 HTTP 客户端,可用于浏览器和 Node.js,提供了丰富的功能和配置选项。
// 安装:npm install axios
// GET 请求
axios.get('https://api.example.com/data')
.then(response => {
console.log('数据:', response.data);
})
.catch(error => {
console.error('错误:', error);
});
// POST 请求
axios.post('https://api.example.com/data', {
name: 'John',
age: 30
}, {
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
console.log('响应:', response.data);
});
// 创建实例
const instance = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000,
headers: { 'X-Custom-Header': 'foobar' }
});
// 使用实例
instance.get('/users')
.then(response => console.log(response.data));
// 并发请求
axios.all([
axios.get('https://api.example.com/users'),
axios.get('https://api.example.com/posts')
])
.then(axios.spread((usersResponse, postsResponse) => {
console.log('用户:', usersResponse.data);
console.log('文章:', postsResponse.data);
}));
// 请求拦截器
axios.interceptors.request.use(
config => {
// 在发送请求前做些什么
config.headers.Authorization = `Bearer ${localStorage.getItem('token')}`;
return config;
},
error => {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 响应拦截器
axios.interceptors.response.use(
response => {
// 对响应数据做点什么
return response;
},
error => {
// 对响应错误做点什么
if (error.response?.status === 401) {
// 处理未授权
window.location.href = '/login';
}
return Promise.reject(error);
}
);
优点:
缺点:
| 特性 | XMLHttpRequest | jQuery Ajax | Fetch API | Axios |
|---|---|---|---|---|
| Promise 支持 | 否 | 否(但可包装) | 是 | 是 |
| async/await | 否 | 否 | 是 | 是 |
| 浏览器支持 | 所有浏览器 | 所有浏览器 | 现代浏览器 | 现代浏览器 + polyfill |
| 请求取消 | 是 | 是 | 是(AbortController) | 是 |
| 超时设置 | 是 | 是 | 否(需手动实现) | 是 |
| 拦截器 | 否 | 是(全局事件) | 否 | 是 |
| 自动 JSON | 否 | 是 | 是(需调用 .json()) | 是 |
| 上传进度 | 是 | 是 | 否 | 是 |
| CSRF 保护 | 手动 | 是 | 手动 | 是 |
| 体积 | 0KB(原生) | ~30KB(jQuery) | 0KB(原生) | ~13KB |
简单项目/原型开发:使用 Fetch API(现代浏览器)或 XMLHttpRequest(兼容性要求高)
已有 jQuery 的项目:继续使用 jQuery Ajax
现代前端应用:推荐使用 Axios(功能全面)或 Fetch API(轻量级需求)
Node.js 环境:Axios(最常用)或 node-fetch(Fetch API 的实现)
// 获取用户列表的四种实现方式
// 1. XMLHttpRequest
function getUsersXHR() {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/users');
xhr.onload = () => resolve(JSON.parse(xhr.responseText));
xhr.onerror = reject;
xhr.send();
});
}
// 2. jQuery
function getUsersjQuery() {
return $.ajax({
url: 'https://api.example.com/users',
method: 'GET',
dataType: 'json'
});
}
// 3. Fetch API
async function getUsersFetch() {
const response = await fetch('https://api.example.com/users');
return response.json();
}
// 4. Axios
async function getUsersAxios() {
const response = await axios.get('https://api.example.com/users');
return response.data;
}
选择哪种方法取决于项目需求:
在实际开发中,Axios 因其功能全面和易于使用而成为当前最受欢迎的选择,特别是对于需要复杂HTTP交互的应用程序。