在现代前端工程中,与后端 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';

// 简单 GET
axios.get('/api/users')
.then(response => console.log(response.data))
.catch(error => console.error('Error:', error));

// 带参数的 GET
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) {
// 服务器返回了错误状态码(如 400, 500)
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', // 必须设置为 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() 创建实例;
  • 通过拦截器统一处理认证与错误;
  • 文件上传/下载务必使用 FormDatablob
  • 利用 onUploadProgress / onDownloadProgress 提升用户体验;
  • 合理使用 AbortController 避免内存泄漏。

掌握 Axios,就等于掌握了一个稳定、高效、可维护的前端通信层。立即在你的项目中试试吧!


参考资料