不再畏惧复杂请求—Axios最完整封装指南
2024-02-17 17:06:06
在 Vue.js 项目开发中,我们常常会使用 Axios 来处理网络请求。Axios 本身是一款功能强大的 HTTP 客户端库,但在实际应用中,为了更好地管理 API、提高代码可维护性和开发效率,我们通常需要对 Axios 进行一些封装。
本文就来探讨一下如何对 Axios 进行封装,使其更符合我们的项目需求。我们会涉及到 API 的集中管理,参数序列化,处理重复请求,以及加载状态和错误处理等方面。
API 的集中管理
当项目中有很多 API 接口时,如果把它们都散落在各个组件中,代码会变得难以维护。我们可以创建一个单独的文件来管理所有的 API 接口,例如 api.js
。
// api.js
const baseUrl = '/api'; // 可以根据实际情况设置
const API = {
user: {
login: `${baseUrl}/user/login`,
getInfo: `${baseUrl}/user/info`
},
article: {
getList: `${baseUrl}/article/list`,
getDetail: `${baseUrl}/article/detail`
}
};
export default API;
然后在组件中,我们就可以通过引入 API
对象来调用相应的接口:
import API from '@/api';
// ...
this.$axios.get(API.article.getList).then(res => {
// 处理数据
});
这样,API 接口的管理就变得更加集中和方便了。
参数序列化
有些 API 接口需要我们传递参数,而不同的接口对参数的格式要求可能不一样。我们可以利用 Axios 的拦截器来统一处理参数序列化。
// axios.js
import axios from 'axios';
import Qs from 'qs'; // 引入 qs 库,用于参数序列化
const instance = axios.create();
// 请求拦截器
instance.interceptors.request.use(config => {
// 如果请求方法是 post 或 put,则将 data 参数序列化
if (config.method === 'post' || config.method === 'put') {
config.data = Qs.stringify(config.data);
}
return config;
}, error => {
return Promise.reject(error);
});
export default instance;
这样,我们就可以在发送请求时,不用再手动对参数进行序列化了。
处理重复请求
有时候,用户可能会在短时间内多次点击同一个按钮,从而发送重复的请求。这不仅会浪费服务器资源,也可能导致一些不可预期的错误。我们可以通过维护一个请求队列来取消重复的请求。
// axios.js
// ...
let pendingRequests = {}; // 存储正在进行的请求
const removePendingRequest = config => {
const requestKey = `${config.url}&${config.method}`;
if (pendingRequests[requestKey]) {
pendingRequests[requestKey]('取消重复请求'); // 取消请求
delete pendingRequests[requestKey];
}
};
// 请求拦截器
instance.interceptors.request.use(config => {
removePendingRequest(config); // 检查是否存在重复请求
config.cancelToken = new axios.CancelToken(c => {
pendingRequests[`${config.url}&${config.method}`] = c;
});
return config;
}, error => {
return Promise.reject(error);
});
// 响应拦截器
instance.interceptors.response.use(response => {
removePendingRequest(response.config); // 请求完成后移除
return response;
}, error => {
if (axios.isCancel(error)) {
console.log('请求已取消', error.message);
} else {
// 处理其他错误
}
return Promise.reject(error);
});
export default instance;
这样,当用户发送重复请求时,之前的请求就会被取消。
加载状态和错误处理
在发送请求时,我们通常会显示一个加载状态,告诉用户正在加载数据。当请求完成后,我们需要隐藏加载状态,并根据响应结果进行相应的处理。
// axios.js
// ...
// 请求拦截器
instance.interceptors.request.use(config => {
// 显示加载状态
// ...
return config;
}, error => {
return Promise.reject(error);
});
// 响应拦截器
instance.interceptors.response.use(response => {
// 隐藏加载状态
// ...
// 处理响应数据
if (response.data.code === 200) {
return response.data;
} else {
// 处理错误
return Promise.reject(response.data);
}
}, error => {
// 隐藏加载状态
// ...
// 处理错误
if (axios.isCancel(error)) {
// ...
} else {
// ...
}
return Promise.reject(error);
});
export default instance;
在加载状态的显示和隐藏方面,我们可以使用一些 UI 组件库,例如 Element UI 或 Ant Design Vue,来实现更友好的用户体验。
常见问题及解答
1. 如何设置请求超时时间?
可以在 axios.create()
方法中设置 timeout
属性,例如 axios.create({ timeout: 5000 })
,表示超时时间为 5 秒。
2. 如何设置请求头?
可以在 axios.create()
方法中设置 headers
属性,例如 axios.create({ headers: { 'Content-Type': 'application/json' } })
。
3. 如何发送 FormData 格式的数据?
可以使用 FormData
对象来构建表单数据,然后将其作为 config.data
传递给 Axios。
4. 如何处理跨域请求?
需要服务器端配合设置 CORS 策略,或者使用代理服务器来转发请求。
5. 如何在请求中携带 Cookie?
可以在 axios.create()
方法中设置 withCredentials: true
。
通过以上这些封装,我们可以使 Axios 更加易用和健壮,从而提高我们的开发效率和代码质量。当然,这只是一个基本的封装示例,您可以根据自己的项目需求进行更深入的定制。