Axios 是一个基于 Promise 的 HTTP 客户端,常用于浏览器和 Node.js 中发送 HTTP 请求。它封装了 XMLHttpRequest 和 Node.js 的 http 模块,使得处理网络请求更加简单和直观,尤其适合处理异步请求。以下是 Axios 的基础概念和使用方法:
1. 安装 Axios
在浏览器或 Node.js 环境中使用前,需要先安装 Axios:
- 在浏览器中直接通过
<script>
引入:
html
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
- 在 Node.js 或现代前端开发项目中通过 npm 或 yarn 安装:
bash
npm install axios
2. 基本使用
发送 GET 请求
javascript
axios.get('https://www.baidu.com/data')
.then(response => {
console.log(response.data); // 成功处理响应数据
})
.catch(error => {
console.error(error); // 错误处理
});
发送 POST 请求
javascript
axios.post('https://www.baidu.com/data', {
name: 'John',
age: 30
})
.then(response => {
console.log(response.data); // 处理成功的响应
})
.catch(error => {
console.error(error); // 错误处理
});
3. Axios 的常见用法
GET 请求(带参数)
javascript
axios.get('https://www.baidu.com/users', {
params: {
id: 123
}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
params
用来将查询参数附加到 URL 中,自动生成类似https://www.baidu.com/users?id=123
的 URL。
POST 请求
javascript
axios.post('https://www.baidu.com/users', {
name: 'Alice',
age: 25
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
- 发送
POST
请求时,通常传递 JSON 格式的数据对象。
并发请求
Axios 提供了同时发送多个请求并等待它们全部完成的功能。
javascript
axios.all([
axios.get('https://www.baidu.com/users'),
axios.get('https://www.baidu.com/posts')
])
.then(axios.spread((usersResponse, postsResponse) => {
console.log(usersResponse.data);
console.log(postsResponse.data);
}));
axios.all()
用于处理多个并发请求,axios.spread()
用于分割响应结果。
4. 设置默认配置
可以通过 axios.defaults
设置全局配置,减少每次请求时重复配置。
设置 Base URL
如果你总是向同一个服务器发送请求,可以设置一个 baseURL
:
javascript
axios.defaults.baseURL = 'https://www.baidu.com/';
axios.get('/users') // 自动将 baseURL 拼接到请求 URL 中
.then(response => console.log(response.data));
设置请求头
javascript
axios.defaults.headers.common['Authorization'] = 'Bearer TOKEN';
这样所有请求都会带有 Authorization
头。
5. 拦截器
拦截器可以在请求或响应被处理之前拦截并修改它们。
请求拦截器
可以在请求发出前修改请求,比如添加认证 Token。
javascript
axios.interceptors.request.use(config => {
config.headers.Authorization = 'Bearer TOKEN';
return config;
}, error => {
return Promise.reject(error);
});
响应拦截器
可以在接收到响应之前对其进行处理,比如检查错误状态码。
javascript
axios.interceptors.response.use(response => {
return response;
}, error => {
if (error.response.status === 401) {
console.error('Unauthorized access!');
}
return Promise.reject(error);
});
6. 取消请求
Axios 支持取消请求,适用于用户撤回操作或重复请求。
javascript
const CancelToken = axios.CancelToken;
let cancel;
axios.get('https://www.baidu.com/data', {
cancelToken: new CancelToken(c => cancel = c)
})
.catch(error => {
if (axios.isCancel(error)) {
console.log('Request canceled', error.message);
}
});
// 调用 cancel 函数可以取消请求
cancel('Operation canceled by the user.');
7. 错误处理
可以通过 .catch()
捕获错误,错误对象包含响应的状态码、请求、消息等信息。
javascript
axios.get('https://www.baidu.com/data')
.catch(error => {
if (error.response) {
console.log(error.response.status); // 错误状态码
console.log(error.response.data); // 错误信息
} else if (error.request) {
console.log(error.request); // 请求未收到响应
} else {
console.log('Error', error.message); // 请求发送前出错
}
});
8. Promise 的使用
Axios 基于 Promise ,可以与 async/await
一起使用,简化异步代码。
javascript
async function fetchData() {
try {
const response = await axios.get('https://www.baidu.com/data');
console.log(response.data);
} catch (error) {
console.error(error);
}
}
fetchData();
9. 配置超时
设置请求超时时间,避免长时间等待无响应。
javascript
axios.get('https://www.baidu.com/data', { timeout: 5000 })
.then(response => console.log(response.data))
.catch(error => console.log('Request timed out', error));
10. 文件上传
Axios 支持通过 FormData
上传文件。
javascript
const formData = new FormData();
formData.append('file', fileInput.files[0]);
axios.post('https://www.baidu.com/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
在上一部分中,我们介绍了 Axios 的基本使用方法、请求类型、配置以及一些高级功能(如拦截器、取消请求、错误处理等)。接下来,我们会继续深入介绍一些更高级的 Axios 特性以及在实际项目中的应用技巧。
11. Axios 的实例化
除了全局的 axios
实例外,你可以创建多个自定义的 Axios 实例,配置不同的 baseURL
、超时设置、请求头等。这样可以为不同的 API 服务端点提供更灵活的配置。
创建 Axios 实例
javascript
const apiClient = axios.create({
baseURL: 'https://www.baidu.com',
timeout: 10000, // 设置超时时间
headers: { 'X-Custom-Header': 'foobar' }
});
// 使用这个实例发出请求
apiClient.get('/users')
.then(response => console.log(response.data))
.catch(error => console.error(error));
- 这种方式适合为不同的 API 端点设置不同的配置,避免全局配置的冲突。
- 常用于大型项目中,分别创建针对不同 API 服务的 Axios 实例。
12. 请求重试
有时由于网络抖动或其他临时错误,请求可能会失败。你可以使用 Axios 来实现请求的重试机制,确保在失败后自动重试请求。
手动实现重试机制
可以使用拦截器来捕获请求失败,并手动重试请求。
javascript
const apiClient = axios.create({ baseURL: 'https://www.baidu.com', timeout: 5000 });
apiClient.interceptors.response.use(null, async (error) => {
const config = error.config;
if (!config || config.__retryCount >= 3) {
return Promise.reject(error);
}
config.__retryCount = config.__retryCount || 0;
config.__retryCount += 1;
return new Promise((resolve) => {
setTimeout(() => {
resolve(apiClient(config)); // 重试请求
}, 1000); // 延迟 1 秒后重试
});
});
apiClient.get('/users')
.then(response => console.log(response.data))
.catch(error => console.error('Failed after retries:', error));
- 每次请求失败后,它会延迟一段时间再尝试重试,最多重试 3 次。
13. 全局错误处理和重定向
在很多情况下,某些错误(例如认证失败、权限不足等)需要进行全局处理,如重定向到登录页面或显示全局错误提示。
全局错误处理
使用 Axios 的拦截器来全局捕获错误,并执行统一的处理逻辑。
javascript
axios.interceptors.response.use(
response => response,
error => {
if (error.response.status === 401) {
// 处理未授权的情况,如重定向到登录页面
window.location = '/login';
} else if (error.response.status === 403) {
// 处理权限不足的情况
alert('You do not have permission to perform this action.');
}
return Promise.reject(error);
}
);
- 这种方法可以确保应用程序中的所有请求错误都得到统一处理,避免在每个请求中重复处理。
14. 取消重复请求
在某些场景下(例如表单提交或数据检索),如果用户在短时间内重复触发相同的请求,最好取消上一次未完成的请求,避免发送不必要的请求和浪费资源。
实现取消重复请求
可以通过 Axios 的 CancelToken
来实现这个功能。
javascript
let cancelToken;
function fetchData() {
if (cancelToken) {
cancelToken.cancel('Previous request canceled');
}
cancelToken = axios.CancelToken.source();
axios.get('https://www.baidu.com/data', {
cancelToken: cancelToken.token
})
.then(response => console.log(response.data))
.catch(error => {
if (axios.isCancel(error)) {
console.log('Request canceled:', error.message);
} else {
console.error(error);
}
});
}
// 用户重复触发请求
fetchData();
fetchData(); // 这会取消上一次请求
- 这种方法可以确保上一次未完成的请求在新请求发出时被取消,节省资源。
15. 设置多种 Content-Type
Axios 可以根据不同的请求类型设置不同的 Content-Type
,例如上传文件时需要使用 multipart/form-data
,而在发送 JSON 数据时使用 application/json
。
根据请求内容设置 Content-Type
javascript
// 发送 JSON 数据
axios.post('/json-endpoint', { name: 'John' }, {
headers: {
'Content-Type': 'application/json'
}
});
// 上传文件,使用 FormData
const formData = new FormData();
formData.append('file', fileInput.files[0]);
axios.post('/upload-endpoint', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
- 根据不同的 API 需求灵活配置请求头,确保服务器能够正确解析请求数据。
16. 上传和下载进度
Axios 支持对文件上传和下载进行进度监听,非常适合上传大文件时给用户反馈当前的上传状态。
上传进度监听
javascript
const formData = new FormData();
formData.append('file', fileInput.files[0]);
axios.post('/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: progressEvent => {
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
console.log(`Upload progress: ${percentCompleted}%`);
}
});
下载进度监听
javascript
axios.get('/large-file-download', {
onDownloadProgress: progressEvent => {
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
console.log(`Download progress: ${percentCompleted}%`);
}
});
onUploadProgress
和onDownloadProgress
提供了一个ProgressEvent
对象,可以获取到loaded
(已加载字节数)和total
(总字节数)来计算完成进度。
17. 高级配置选项
Axios 允许设置一些高级选项来控制请求的行为,如 validateStatus
、transformRequest
和 transformResponse
。
自定义状态码验证
你可以通过 validateStatus
自定义哪些状态码被认为是成功响应。
javascript
axios.get('/api', {
validateStatus: function (status) {
return status < 500; // 处理 500 以内的状态码为成功
}
})
.then(response => console.log(response))
.catch(error => console.error(error));
请求和响应数据的转换
可以通过 transformRequest
和 transformResponse
在请求发送前或响应接收后对数据进行处理。
javascript
axios.post('/api', { name: 'John' }, {
transformRequest: [(data, headers) => {
// 自定义请求数据的转换逻辑
data.name = data.name.toUpperCase();
return JSON.stringify(data);
}],
transformResponse: [(data) => {
// 自定义响应数据的转换逻辑
data = JSON.parse(data);
data.receivedAt = new Date();
return data;
}]
});
18. 处理跨域请求
如果 Axios 请求的 API 地址与当前应用不在同一个域名下(跨域),需要在服务器上配置 CORS(跨域资源共享)支持。
配置跨域请求
javascript
axios.get('https://www.baidu.com/data', {
withCredentials: true // 如果 API 需要传递认证信息(如 Cookies)
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
withCredentials
允许跨域请求时携带认证信息,如 Cookies。