Axios vs Fetch API 对比
Axios 和 Fetch API 都是用于发送 HTTP 请求的工具,但它们在功能、易用性和兼容性方面存在显著差异。
核心区别对比表
| 特性 | Axios | Fetch API |
|---|---|---|
| API 设计 | 基于 Promise,API 更友好 | 原生 Promise,API 较底层 |
| JSON 处理 | 自动转换 JSON 数据 | 需要手动调用 .json() |
| 请求拦截器 | ✅ 原生支持 | ❌ 需要自行封装 |
| 响应拦截器 | ✅ 原生支持 | ❌ 需要自行封装 |
| 请求取消 | ✅ 支持 AbortController | ✅ 支持 AbortController |
| 超时设置 | ✅ 原生支持 timeout | ❌ 需要手动实现 |
| 进度监控 | ✅ 原生支持 onUploadProgress/onDownloadProgress | ❌ 需要手动实现 |
| 错误处理 | HTTP 错误自动 reject | 只有网络错误才 reject |
| 浏览器兼容 | IE11+ | Chrome 42+, Edge 14+, Firefox 39+ |
| 体积 | ~13KB (gzip) | 原生支持,无额外体积 |
| Node.js 支持 | ✅ 支持 | ❌ 不支持(需 polyfill) |
详细对比分析
1. JSON 数据处理
Axios(自动处理):
javascript// 自动将响应转换为 JSON const response = await axios.get('/api/users'); console.log(response.data); // 已经是 JavaScript 对象 // 自动将请求体转换为 JSON await axios.post('/api/users', { name: 'John' });
Fetch(手动处理):
javascript// 需要手动调用 .json() const response = await fetch('/api/users'); const data = await response.json(); // 额外的 await console.log(data); // 需要手动设置 headers 和 stringify await fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'John' }) });
2. 错误处理
Axios(自动处理 HTTP 错误):
javascripttry { const response = await axios.get('/api/not-found'); } catch (error) { // 404 会进入 catch console.log(error.response.status); // 404 }
Fetch(需要手动检查状态):
javascriptconst response = await fetch('/api/not-found'); // 需要手动检查状态码 if (!response.ok) { // 404 不会自动进入 catch throw new Error(`HTTP error! status: ${response.status}`); }
3. 超时设置
Axios(原生支持):
javascriptaxios.get('/api/data', { timeout: 5000 // 5秒超时 });
Fetch(需要手动实现):
javascriptconst fetchWithTimeout = (url, options = {}, timeout = 5000) => { return Promise.race([ fetch(url, options), new Promise((_, reject) => setTimeout(() => reject(new Error('Request timeout')), timeout) ) ]); };
4. 拦截器
Axios(原生支持):
javascript// 请求拦截器 axios.interceptors.request.use(config => { config.headers.Authorization = `Bearer ${token}`; return config; }); // 响应拦截器 axios.interceptors.response.use( response => response.data, error => { if (error.response.status === 401) { redirectToLogin(); } return Promise.reject(error); } );
Fetch(需要自行封装):
javascript// 需要创建包装函数 const fetchWithAuth = (url, options = {}) => { return fetch(url, { ...options, headers: { ...options.headers, 'Authorization': `Bearer ${token}` } }); };
5. 进度监控
Axios(原生支持):
javascriptaxios.post('/api/upload', formData, { onUploadProgress: (progressEvent) => { const percent = Math.round( (progressEvent.loaded * 100) / progressEvent.total ); console.log(`上传进度: ${percent}%`); } });
Fetch(需要手动实现):
javascript// Fetch 没有原生进度支持,需要使用 ReadableStream const response = await fetch('/api/download'); const reader = response.body.getReader(); while (true) { const { done, value } = await reader.read(); if (done) break; // 手动计算进度 }
选择建议
使用 Axios 的场景
-
需要拦截器功能
- 统一添加认证 Token
- 统一错误处理
- 统一日志记录
-
需要进度监控
- 文件上传下载
- 大文件传输
-
需要超时控制
- 防止请求挂起
- 提升用户体验
-
项目复杂度较高
- 多个 API 服务
- 复杂的错误处理逻辑
- 需要请求重试机制
-
需要 IE 支持
- 需要兼容 IE11
-
Node.js 环境
- 服务端渲染
- Node.js 脚本
使用 Fetch 的场景
-
追求最小体积
- 对包体积敏感的项目
- 简单的单页面应用
-
现代浏览器环境
- 不需要 IE 支持
- 现代框架(Next.js, Remix 等)
-
简单的 HTTP 请求
- 不需要复杂的拦截器
- 简单的 GET/POST 请求
-
学习目的
- 理解底层 HTTP API
- 教学演示
现代框架中的选择
React/Vue/Angular 项目
javascript// 推荐使用 Axios import axios from 'axios'; const api = axios.create({ baseURL: process.env.VUE_APP_API_URL, timeout: 10000 }); // 添加拦截器 api.interceptors.request.use(config => { const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; });
Next.js / Remix 项目
javascript// 可以使用 Fetch(配合框架的数据获取函数) // app/page.js (Next.js App Router) async function getData() { const res = await fetch('https://api.example.com/data', { next: { revalidate: 3600 } // 缓存配置 }); if (!res.ok) { throw new Error('Failed to fetch'); } return res.json(); }
总结
| 场景 | 推荐工具 |
|---|---|
| 企业级应用 | Axios |
| 需要拦截器 | Axios |
| 文件上传下载 | Axios |
| 需要超时控制 | Axios |
| 需要 IE 支持 | Axios |
| Node.js 环境 | Axios |
| 简单项目 | Fetch |
| 对体积敏感 | Fetch |
| 现代浏览器 | Fetch |
| 学习目的 | Fetch |
一般建议:
- 中大型项目、需要复杂 HTTP 处理 → 选择 Axios
- 小型项目、简单请求、追求轻量 → 选择 Fetch