一、前言
在 Vue 项目开发中,我们几乎每天都要与后端 API 打交道 ------ 登录、获取数据、提交表单、上传文件......这些都离不开 Ajax(异步请求)。
虽然现代浏览器原生支持 fetch,但大多数 Vue 项目仍然选择使用第三方库,比如 Axios。为什么?它们之间有什么区别?什么时候该用哪个?
本文将带你深入对比 Vue 项目中最常用的两个 Ajax 方案:
✅ Axios (第三方库)
✅ Fetch API(浏览器原生)
从语法、功能、错误处理、拦截器、兼容性等多个维度全面解析,助你做出更合理的技术选型。
二、先看结论:一句话总结
| 库名 | 一句话总结 |
|---|---|
| Axios | 功能强大、语法简洁、拦截器完善,Vue 项目首选 |
| Fetch | 原生支持、无需引入、轻量,适合简单请求或现代项目 |
📌 推荐结论:
- ✅ 大多数 Vue 项目推荐使用 Axios
- ✅ 轻量级项目或学习用途可尝试 Fetch
三、基本语法对比
1. Axios 发送 GET 请求
javascript
import axios from 'axios'
axios.get('/api/users')
.then(response => {
console.log(response.data)
})
.catch(error => {
console.error('请求失败:', error)
})
2. Fetch 发送 GET 请求
javascript
fetch('/api/users')
.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)
})
🔍 第一印象:
- Axios 语法更简洁,
response.data直接拿到数据 - Fetch 需手动判断
response.ok,并调用.json()解析
四、核心功能对比表
| 功能特性 | Axios | Fetch |
|---|---|---|
| ✅ 基于 Promise | ✔️ | ✔️ |
| ✅ 浏览器兼容性 | IE9+(需 polyfill) | IE 不支持,现代浏览器原生支持 |
| ✅ 请求/响应拦截器 | ✔️ 支持,可统一处理 token、loading | ❌ 不支持,需手动封装 |
| ✅ 自动转换 JSON 数据 | ✔️ 默认解析 response.data |
❌ 需手动调用 .json() |
| ✅ 错误处理更友好 | ✔️ 网络错误、HTTP 错误统一抛出 | ❌ HTTP 404/500 不触发 catch,需手动判断 |
| ✅ 超时设置 | ✔️ timeout: 5000 |
❌ 原生不支持,需用 AbortController |
| ✅ 取消请求 | ✔️ 使用 CancelToken 或 AbortController |
✔️ 使用 AbortController |
| ✅ 上传进度监听 | ✔️ 支持 onUploadProgress |
❌ 不支持 |
| ✅ 下载进度监听 | ✔️ 支持 onDownloadProgress |
❌ 不支持 |
| ✅ 默认携带 Cookie | ❌ 需设置 withCredentials: true |
❌ 需设置 credentials: 'include' |
💡 Axios 在功能丰富性和开发体验上明显胜出。
五、实战代码示例
✅ 场景 1:POST 提交数据(Axios)
javascript
axios.post('/api/login', {
username: 'admin',
password: '123456'
}, {
headers: {
'Content-Type': 'application/json'
},
withCredentials: true // 携带 Cookie
})
.then(res => {
console.log('登录成功', res.data)
})
✅ 场景 1:POST 提交数据(Fetch)
javascript
fetch('/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: 'admin',
password: '123456'
}),
credentials: 'include' // 携带 Cookie
})
.then(res => {
if (!res.ok) throw new Error('登录失败')
return res.json()
})
.then(data => {
console.log('登录成功', data)
})
✅ 场景 2:请求拦截器(Axios 独有)
javascript
// 添加请求拦截器
axios.interceptors.request.use(config => {
// 每次请求前添加 token
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
// 显示 loading
showLoading()
return config
})
// 添加响应拦截器
axios.interceptors.response.use(
response => {
hideLoading()
return response
},
error => {
hideLoading()
if (error.response?.status === 401) {
alert('登录已过期,请重新登录')
router.push('/login')
}
return Promise.reject(error)
}
)
📌 这是 Axios 最大的优势之一:可以全局统一处理认证、错误、loading 状态。
六、在 Vue 项目中如何选择?
推荐使用 Axios 的场景 ✅
| 场景 | 说明 |
|---|---|
| 中大型项目 | 需要统一管理请求、错误、token |
| 需要上传/下载进度 | Axios 原生支持 |
| 需要兼容老浏览器 | Axios + polyfill 支持 IE9+ |
| 团队协作项目 | 拦截器 + 封装更规范 |
可以考虑 Fetch 的场景 ⚠️
| 场景 | 说明 |
|---|---|
| 轻量级项目 | 无需引入额外依赖 |
| 学习用途 | 理解原生 API 更好 |
| 现代浏览器环境 | 如 Electron、内部管理系统 |
| 已使用其他请求库 | 如 ky、swrv 等封装库 |
七、如何在 Vue 项目中安装和使用 Axios?
1. 安装 Axios
bash
npm install axios
2. 封装请求模块(推荐)
javascript
// utils/request.js
import axios from 'axios'
const request = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000
})
// 请求拦截器
request.interceptors.request.use(config => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
// 响应拦截器
request.interceptors.response.use(
response => response.data,
error => {
return Promise.reject(error)
}
)
export default request
3. 在组件中使用
javascript
import request from '@/utils/request'
export default {
async created() {
try {
const data = await request.get('/users')
this.users = data
} catch (error) {
console.error('请求失败:', error)
}
}
}
八、Fetch 的现代替代方案
如果你喜欢 Fetch 的原生感,但又想要更好的开发体验,可以考虑以下封装库:
| 库名 | 特点 |
|---|---|
ky |
基于 Fetch 的轻量级封装,API 更友好 |
swrv |
带缓存的 Fetch,适合数据频繁请求场景 |
axios |
老牌王者,功能全面 |
九、常见问题解答
❓ 问题 1:Fetch 为什么 HTTP 错误不进 catch?
因为 fetch 只在网络错误时 reject,HTTP 状态码 4xx/5xx 仍属于"成功响应",需手动判断:
javascript
if (!response.ok) {
throw new Error(`HTTP ${response.status}`)
}
❓ 问题 2:Axios 会增加打包体积吗?
会,但很小(约 15KB gzip),功能带来的便利远大于体积成本。
❓ 问题 3:Vue 3 中推荐用哪个?
官方不强制,但社区普遍使用 Axios,尤其在企业项目中。
十、总结
| 对比项 | Axios | Fetch |
|---|---|---|
| 学习成本 | 低,API 简洁 | 中,需处理更多细节 |
| 功能丰富度 | 高(拦截器、进度、超时) | 低(原生功能有限) |
| 错误处理 | 友好,自动抛出 | 需手动判断 response.ok |
| 兼容性 | IE9+(需 polyfill) | 不支持 IE |
| 是否推荐 | ✅ 强烈推荐 | ⚠️ 仅限轻量或学习 |
十一、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!