axios本身功能已经很强大了,封装也无需过度,只要能满足自己项目的需求即可。
常规axios封装,只需要设置:
- 实现请求拦截
- 实现响应拦截
- 常见错误信息处理
- 请求头设置
javascript
import axios from 'axios';
// 创建axios实例
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // api的base_url
timeout: 5000 // 请求超时时间
});
// 请求拦截器
service.interceptors.request.use(
config => {
// 可以在这里添加请求头等信息
// 例如:config.headers['Authorization'] = 'your token';
// config.data = qs.stringify(config.data); // 序列化,比如表单数据
return config;
},
error => {
// 请求错误处理
return Promise.reject(error);
}
);
// 响应拦截器
service.interceptors.response.use(
response => {
// 对响应数据做处理,例如只返回data部分
const res = response.data;
// 如果返回的状态码为200,说明成功,可以直接返回数据
if (res.code === 200) {
return res;
} else {
// 返回的状态码非200,说明有错误,此处可以根据后端返回的错误码进行进一步处理
return Promise.reject(res || 'error');
}
},
error => {
// 服务器返回的错误处理
return Promise.reject(error);
}
);
export default service;
需要取消接口调用的场景:
- 假如一个页面接口太多、或者当前网络太卡顿、这个时候跳往其他路由,当前页面可以做的就是把请求中断掉;(优化)
- 假如当前接口调取了第一页数据,又调去了第二页的数据,当我们调取第二页数据时就需要把第一页数据的请求中断掉; (常见于在搜索大数据)
- tab频繁切换,取消切换前的tab接口请求;
- 取消下载。
AbortController 取消接口请求:
从 v0.22.0 开始,Axios 支持以 fetch API 方式------ AbortController 取消请求。AbortController 接口表示一个控制器对象,允许你根据需要中止一个或多个 Web 请求。
代码实现:
1、将中止控制器传递给 axios 的 调去接口的方法controller = new AbortController()
2、axios里面有定义标识的属性signal
3、点击取消:controller.abort()
javascript
const controller = new AbortController();
axios.get('/foo/bar', {
signal: controller.signal
}).then(function(response) {
//...
});
// 取消请求
controller.abort()
需要重发的场景:
比如有重要的接口,一旦调取失败会影响整个页面的展示和使用,在用户网络不好等情况下导致接口调用失败。
解决:
在响应拦截返回失败时进行重试:设置重试次数的参数,再次发送请求
模拟 axios timeout: 2000,服务端加个延时3s。
axios里面设置两个参数:{
retries: 3, // 设置重试次数为3次
retryDelay: 1000, // 设置重试的间隔时间
}
完整代码:
javascript
<script setup lang="ts">
import axios from 'axios'
const request = axios.create({
baseURL: 'http://localhost:3000',
// 设置请求超时时间为2秒
timeout: 2000,
retries: 3, // 设置重试次数为3次
retryDelay: 1000, // 设置重试的间隔时间
} as any)
// 添加响应拦截器
request.interceptors.response.use(
(response) => {
// 对响应数据做些什么
return Promise.resolve(response.data)
},
(error) => {
const config = error.config
// 如果config不存在或未设置重试选项,则拒绝
if (!config || !config.retries) {
return Promise.reject(error)
}
// 设置变量来跟踪重试次数
config.__retryCount = config.__retryCount || 0
// 检查是否达到最大重试次数
if (config.__retryCount >= config.retries) {
return Promise.reject(error)
}
// 增加重试计数器
config.__retryCount += 1
// 创建一个新的Promise来处理每次重试之前等待一段时间
const backoff = new Promise((resolve) => {
setTimeout(() => {
resolve('重新请求:' + config.__retryCount)
}, config.retryDelay || 1)
})
// 返回Promise,以便Axios知道我们已经处理了错误
return backoff.then((txt) => {
console.log(txt)
return request(config)
})
},
)
// 请求中止控制器
let controller: AbortController
// --- 获取数据 ---
const getData = async () => {
controller = new AbortController()
const res = await request({
signal: controller.signal, // 添加请求中止标识
method: 'GET',
url: '/delay_3s_data',
})
console.log('成功', res)
}
const stop = () => {
// 中止网络请求
controller.abort()
console.log('取消')
}
</script>
<template>
<h1>axios请求重试</h1>
<button @click="getData()">发送请求</button>
<button @click="stop()">中止请求</button>
</template>