全面掌握 Axios:功能强大且易用的 HTTP 客户端
在现代前端工程中,与后端 API 交互是不可或缺的一环。虽然浏览器原生提供了 fetch API,但在实际项目中,Axios 凭借其简洁的 API、强大的功能和良好的兼容性,成为绝大多数开发者的首选 HTTP 客户端。本文将系统性地介绍 Axios 的使用方法,从基础请求到高级场景(如上传/下载进度监控、请求拦截、取消请求等),助你全面掌握这一利器。
一、什么是 Axios?
Axios 是一个基于 Promise 的 HTTP 客户端,可用于浏览器和 Node.js 环境。它具有以下核心优势:
- 自动转换 JSON 数据
- 支持请求和响应拦截器
- 内置客户端 XSRF(CSRF)防护
- 支持上传/下载进度事件
- 可取消请求(CancelToken / AbortController)
- 兼容 IE(需 polyfill Promise)
- 支持 TypeScript
✅ 安装方式:
1 2 3
| npm install axios
yarn add axios
|
二、基础用法
1. GET 请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import axios from 'axios';
axios.get('/api/users') .then(response => console.log(response.data)) .catch(error => console.error('Error:', error));
axios.get('/api/search', { params: { q: 'javascript', page: 1 } }).then(res => console.log(res.data));
|
2. POST 请求(发送 JSON)
1 2 3 4 5 6
| axios.post('/api/users', { name: 'Bob', email: 'bob@example.com' }) .then(res => console.log('Created:', res.data)) .catch(err => console.error(err));
|
3. 使用 async/await
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| async function createUser() { try { const res = await axios.post('/api/users', { name: 'Alice' }); console.log(res.data); } catch (error) { if (error.response) { console.log('Error status:', error.response.status); console.log('Error data:', error.response.data); } else if (error.request) { console.log('No response received:', error.request); } else { console.log('Error message:', error.message); } } }
|
三、上传文件(带进度条)
Axios 原生支持通过 onUploadProgress 监听上传进度,非常适合实现上传进度条。
示例:上传单个文件并显示进度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <input type="file" id="fileInput" /> <progress id="uploadProgress" value="0" max="100"></progress> <div id="progressText">0%</div>
<script type="module"> import axios from 'axios';
document.getElementById('fileInput').addEventListener('change', async (e) => { const file = e.target.files[0]; if (!file) return;
const formData = new FormData(); formData.append('file', file);
const progressBar = document.getElementById('uploadProgress'); const progressText = document.getElementById('progressText');
try { const response = await axios.post('/api/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' }, onUploadProgress: (progressEvent) => { if (progressEvent.total) { const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total); progressBar.value = percent; progressText.textContent = `${percent}%`; } } });
console.log('上传成功:', response.data); } catch (error) { console.error('上传失败:', error); } }); </script>
|
🔔 注意:虽然可以手动设置 Content-Type,但更推荐不设置,让浏览器自动填充正确的 multipart/form-data; boundary=...。
四、下载文件(带进度展示)
Axios 通过 onDownloadProgress 提供下载进度监听,结合 responseType: 'blob' 可实现带进度的文件下载。
示例:下载大文件并显示进度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| async function downloadWithProgress(url, filename) { const progressBar = document.getElementById('downloadProgress'); const progressText = document.getElementById('downloadPercent');
try { const response = await axios({ url: url, method: 'GET', responseType: 'blob', onDownloadProgress: (progressEvent) => { if (progressEvent.total) { const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total); progressBar.value = percent; progressText.textContent = `${percent}%`; } } });
const urlBlob = window.URL.createObjectURL(new Blob([response.data])); const link = document.createElement('a'); link.href = urlBlob; link.setAttribute('download', filename); document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(urlBlob); } catch (error) { console.error('下载失败:', error); } }
downloadWithProgress('/api/report.zip', '报告.zip');
|
💡 提示:onDownloadProgress 在浏览器中依赖于响应头 Content-Length,若后端未正确设置,可能无法获取总大小。
五、高级功能
1. 请求与响应拦截器
拦截器可用于统一添加 token、日志记录、错误处理等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| axios.interceptors.request.use( config => { const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, error => Promise.reject(error) );
axios.interceptors.response.use( response => response, error => { if (error.response?.status === 401) { window.location.href = '/login'; } return Promise.reject(error); } );
|
2. 取消请求(AbortController)
Axios 支持使用 AbortController(推荐)或旧版 CancelToken。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const controller = new AbortController();
axios.get('/api/long-task', { signal: controller.signal }) .then(res => console.log(res.data)) .catch(err => { if (axios.isCancel(err)) { console.log('请求已取消'); } });
controller.abort();
|
3. 创建实例(推荐用于项目)
为不同 API 创建独立实例,便于管理基础 URL、超时、拦截器等。
1 2 3 4 5 6 7 8
| const apiClient = axios.create({ baseURL: 'https://api.example.com', timeout: 10000, headers: { 'X-Custom-Header': 'foobar' } });
apiClient.get('/users').then(...);
|
六、Axios vs Fetch
| 特性 |
Axios |
Fetch |
| 浏览器兼容性 |
✅(支持 IE,需 polyfill) |
❌(IE 不支持) |
| 自动 JSON 转换 |
✅ |
❌(需手动 .json()) |
| 请求/响应拦截 |
✅ |
❌ |
| 上传/下载进度 |
✅ |
❌ |
| 取消请求 |
✅(AbortController) |
✅(但需手动处理) |
| 错误处理 |
✅(HTTP 错误自动 reject) |
❌(需手动检查 ok) |
| 体积 |
较大(~13KB gzipped) |
原生,无额外体积 |
📌 结论:
- 简单项目或追求轻量 → 用 Fetch
- 中大型项目、需进度/拦截/兼容性 → 用 Axios
七、总结
Axios 以其功能全面、API 友好、生态成熟的特点,成为前端网络请求的事实标准。无论是普通 CRUD、文件上传下载,还是复杂的拦截、取消、进度监控,Axios 都能优雅应对。
✅ 最佳实践建议:
- 使用
axios.create() 创建实例;
- 通过拦截器统一处理认证与错误;
- 文件上传/下载务必使用
FormData 和 blob;
- 利用
onUploadProgress / onDownloadProgress 提升用户体验;
- 合理使用
AbortController 避免内存泄漏。
掌握 Axios,就等于掌握了一个稳定、高效、可维护的前端通信层。立即在你的项目中试试吧!
参考资料: