Ajax
、Axios
和 Fetch
都是用于在浏览器中发起 HTTP 请求以实现异步数据交互的技术,但它们在概念层级、API 设计和功能上存在显著区别。
1. Ajax (Asynchronous JavaScript and XML)
- 本质:不是一个具体的 API 或库,而是一种技术概念或编程范式。它描述了使用 JavaScript(通常是
XMLHttpRequest
对象)在后台与服务器交换数据,从而异步更新网页部分内容,而无需重新加载整个页面。 - 核心实现:在现代浏览器中,Ajax 通常通过原生的
XMLHttpRequest
(XHR) 对象来实现。 - 特点:
- 底层:直接操作
XMLHttpRequest
对象,代码相对繁琐。 - 兼容性:非常好,支持非常老的浏览器。
- 默认行为:发送请求时,不会自动携带 Cookie(需要设置
withCredentials
)。 - 错误处理:网络错误和 HTTP 错误(如 404, 500)的处理方式不一致,需要手动判断
status
。 - 取消请求:可以通过
xhr.abort()
取消。
- 底层:直接操作
- 示例:
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
console.log(xhr.responseText);
} else {
console.error('Error');
}
}
};
xhr.send();
2. Axios
- 本质:一个基于 Promise 的 第三方 HTTP 客户端库。它可以用在浏览器和 Node.js 环境中。
- 特点:
- 易用性:API 设计简洁、优雅,使用
async/await
或.then()
非常方便。 - 功能丰富:
- 自动转换:自动将请求和响应数据在 JSON 和 JavaScript 对象之间转换。
- 请求/响应拦截器:可以在请求发送前或响应到达后统一处理(如添加 token、错误处理)。
- 默认携带 Cookie:在浏览器中,默认会发送和接收 Cookie(
withCredentials: true
)。 - 取消请求:提供
CancelToken
或AbortController
API 来取消请求。 - 超时设置:可以轻松设置请求超时。
- 错误处理:将网络错误和 HTTP 错误都通过 Promise 的
reject
抛出,便于统一用catch
处理。
- 兼容性:需要引入库文件,不支持 IE8 及以下。
- 易用性:API 设计简洁、优雅,使用
- 示例:
axios.get('/api/data')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
// 或使用 async/await
try {
const response = await axios.get('/api/data');
console.log(response.data);
} catch (error) {
console.error(error);
}
3. Fetch
- 本质:浏览器原生提供的 现代 API,用于发起网络请求。它是
XMLHttpRequest
的现代替代方案,基于 Promise。 - 特点:
- 原生支持:无需引入第三方库,现代浏览器(除 IE 外)都支持。
- API 设计:返回一个 Promise,但有一个重要陷阱:
fetch
的 Promise 只有在网络错误时才会 reject。对于 HTTP 状态码错误(如 404, 500),Promise 仍然会 resolve。你需要手动检查response.ok
或response.status
来判断请求是否成功。 - 默认行为:不会自动携带 Cookie(需要在
options
中设置credentials: 'include'
)。 - 数据处理:响应体是流式的,需要调用
response.json()
、response.text()
等方法来解析,这些方法也返回 Promise。 - 取消请求:可以使用
AbortController
API。 - 错误处理:需要额外代码来处理 HTTP 错误状态。
- 示例:
fetch('/api/data', {
credentials: 'include' // 如果需要发送 Cookie
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Error:', error);
});
// 或使用 async/await
try {
const response = await fetch('/api/data');
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
核心区别总结
特性 | Ajax (XMLHttpRequest ) | Axios | Fetch |
---|---|---|---|
类型 | 技术概念 / 底层 API | 第三方库 | 原生 API |
基于 | XHR 对象 | Promise | Promise |
易用性 | 较低,代码繁琐 | 高,API 优雅 | 中等,有陷阱 |
错误处理 | 需手动判断 status | 统一通过 catch 处理 | 需手动检查 response.ok |
自动 JSON 转换 | 否 | 是 | 否(需 response.json() ) |
默认携带 Cookie | 否 | 是 | 否 |
拦截器 | 无 | 有 | 无 |
取消请求 | xhr.abort() | CancelToken / AbortController | AbortController |
浏览器支持 | 极好(包括老浏览器) | 需引入,不支持 IE | 现代浏览器(不支持 IE) |
Node.js 支持 | 需 xhr2 库 | 支持 | 需 polyfill 或现代 Node.js |
如何选择?
- 需要兼容老浏览器(如 IE)? → 使用
XMLHttpRequest
(Ajax) 或Axios
。 - 项目已使用 Axios 或需要其高级功能(拦截器、自动转换)? → 优先使用
Axios
。 - 追求轻量、无依赖,且目标浏览器支持? → 使用
Fetch
,但务必记得处理 HTTP 错误状态。 - 在 Node.js 中发起请求? → 使用
Axios
或 Node.js 内置的http
/https
模块(fetch
在较新版本 Node.js 中可用)。
简单来说:
Ajax
是老派方法,Axios
是功能强大的“瑞士军刀”,Fetch
是现代化的原生选择,但使用时要小心它的“陷阱”。
THE END