
XMLHttpRequest、Fetch、AJAX与Axios的对比解析
一、基本概念
1. AJAX(Asynchronous JavaScript and XML)
-
定义:并非特定技术,而是一种通过JavaScript进行异步数据交互的编程模式
-
核心:在不刷新整个页面的情况下,与服务器进行异步通信并更新部分网页
-
历史:诞生于2005年前后,以XML作为主要数据交换格式(现代已被JSON取代)
-
技术依赖:最初依赖
XMLHttpRequest,现代可基于Fetch API实现
2. XMLHttpRequest(XHR)
-
定义:浏览器提供的原生API,用于在浏览器和服务器之间进行异步通信
-
特点:
- 诞生于IE5时代,是AJAX的核心技术
- API复杂,需手动处理状态码、请求头、响应格式等
- 兼容性好,支持所有主流浏览器(包括IE6+)
3. Fetch API
-
定义:ES6引入的新一代HTTP请求API,基于Promise实现
-
特点:
- 语法更简洁、灵活,支持链式调用和async/await
- 原生支持Promise,避免回调地狱
- 浏览器原生支持(IE除外)
4. Axios
-
定义:基于Promise的HTTP客户端库,用于浏览器和Node.js环境
-
特点:
- 封装了XMLHttpRequest和Fetch的功能,提供更高级的API
- 自动处理JSON序列化和反序列化
- 支持请求/响应拦截器、请求取消、自动重试等
- 服务器端支持Node.js的http模块
二、技术对比表
| 特性 |
XMLHttpRequest |
Fetch API |
Axios |
| API风格 |
回调函数(易嵌套) |
Promise链式调用 |
Promise/async-await |
| 错误处理 |
需手动检查状态码 |
HTTP错误不触发catch |
统一的错误处理 |
| JSON处理 |
手动解析/序列化 |
需调用res.json() |
自动处理JSON |
| 拦截器 |
无 |
无(需手动实现) |
内置支持 |
| 请求取消 |
xhr.abort() |
AbortController |
cancelToken |
| 进度监听 |
支持onprogress |
需手动实现 |
支持uploadProgress |
| 兼容性 |
所有浏览器(IE6+) |
现代浏览器(IE除外) |
IE11+(需polyfill) |
| 默认携带Cookies |
是 |
否(需手动配置) |
是 |
| 服务器端支持 |
仅浏览器 |
仅浏览器 |
浏览器+Node.js |
三、代码示例对比
1. 基本GET请求
// XMLHttpRequest
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(JSON.parse(xhr.responseText));
}
};
xhr.send();
// Fetch API
fetch('/api/data')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
// Axios
axios.get('/api/data')
.then(res => console.log(res.data))
.catch(err => console.error(err));
2. 带参数的POST请求
// XMLHttpRequest
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/login', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(JSON.parse(xhr.responseText));
}
};
xhr.send(JSON.stringify({ username: 'test', password: '123' }));
// Fetch API
fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'test', password: '123' })
})
.then(res => res.json())
.then(data => console.log(data));
// Axios
axios.post('/api/login', {
username: 'test',
password: '123'
})
.then(res => console.log(res.data));
3. 请求拦截器
// Axios(内置支持)
axios.interceptors.request.use(config => {
config.headers.Authorization = 'Bearer token';
return config;
});
// Fetch(需手动封装)
const fetchWithToken = (url, options = {}) => {
const headers = { ...options.headers, 'Authorization': 'Bearer token' };
return fetch(url, { ...options, headers });
};
4. 请求取消
// XMLHttpRequest
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/large-data');
xhr.send();
// 取消请求
xhr.abort();
// Fetch API
const controller = new AbortController();
fetch('/api/large-data', { signal: controller.signal })
.catch(err => {
if (err.name === 'AbortError') console.log('请求已取消');
});
// 取消请求
controller.abort();
// Axios
const source = axios.CancelToken.source();
axios.get('/api/large-data', { cancelToken: source.token })
.catch(err => {
if (axios.isCancel(err)) console.log('请求已取消', err.message);
});
// 取消请求
source.cancel('用户取消请求');
四、错误处理对比
1. HTTP错误(如404、500)
// Fetch API:需手动检查状态码
fetch('/api/not-found')
.then(res => {
if (!res.ok) throw new Error(`HTTP错误: ${res.status}`);
return res.json();
})
.catch(err => console.error(err)); // 不会捕获404错误,需手动throw
// Axios:统一处理所有错误
axios.get('/api/not-found')
.catch(err => {
if (err.response) {
console.error('HTTP错误:', err.response.status);
} else if (err.request) {
console.error('请求已发送,但无响应');
} else {
console.error('请求设置时出错:', err.message);
}
});
五、适用场景推荐
| 场景 |
推荐技术 |
理由 |
| 兼容老旧浏览器(如IE6+) |
XMLHttpRequest |
唯一选择 |
| 轻量级应用,追求原生API |
Fetch API |
无需额外依赖,语法简洁 |
| 企业级应用,需要全面功能 |
Axios |
内置拦截器、取消请求、自动重试等,减少重复开发 |
| 前后端同构应用 |
Axios |
同时支持浏览器和Node.js |
| 需监听上传/下载进度 |
XMLHttpRequest或Axios |
XMLHttpRequest原生支持,Axios提供简化API |
| 小型项目,快速实现 |
Fetch API |
无需安装额外依赖,适合简单场景 |
六、总结
-
技术演进路线:XMLHttpRequest → Fetch API → Axios
-
核心差异:
-
XMLHttpRequest:最早的API,功能完整但使用繁琐
-
Fetch API:现代原生API,语法简洁,Promise支持,但功能不够完善
-
Axios:功能最全面的库,提供高级特性(拦截器、取消请求、自动重试),开发体验最佳
-
选择建议:优先使用Axios,除非项目有特殊限制(如兼容IE或追求极致轻量化)