前端Axios失败重试
前端Axios失败重试
失败重试次数写在vite全局配置中,之后统一修改即可
vite环境变量
# 失败重试次数 VITE_BASE_API_RETRY=5 # 失败重试时间 VITE_BASE_API_RETRY_DELAY=3000
Axios重试
思路
- 在Axios创建中读取vite环境变量配置,将其赋值
- 在发送请求时,如果出错不返回也就是不return之后设置定时器去重试之前的请求
- 写在Axios中好处是不用一个一个去配置了
- 当重试次数大于约定次数则返回
- 如果期间成功了就回到主页
未解决问题
- 本来想的是,如果失败了就跳转到失败页这样在失败页中做一些失败的显示,比如重试次数之类显示
- 如果使用windows.lcoation方式跳转,在我的谷歌浏览器中会将进行弹窗拦截无法实现跳转,解决无法跳转问题移入vuerouter
- 如果请求成功后本来想的是,成功就返回上一次页面,但是会出现页面跳来跳去问题只能让它成功后跳转到固定页面
- 因为自定义的配置Axios不支持会报错Vue: Object literal may only specify known properties, and 'retry' does not exist in type 'CreateAxiosDefaults'.
定义Axios变量
在创建请求时将重试次数和时间放入到Axios配置中
const request = axios.create({ // 默认请求地址 baseURL: import.meta.env.VITE_BASE_API, // 设置超时时间 timeout: import.meta.env.VITE_BASE_API_TIMEOUT, retry: import.meta.env.VITE_BASE_API_RETRY, //设置全局重试请求次数(最多重试几次请求) retryDelay: import.meta.env.VITE_BASE_API_RETRY_DELAY, //设置全局请求间隔 // 跨域允许携带凭证 // withCredentials: true, });
失败重试
失败的emit
在error.config中可以获取到之前在Axios配置中的变量
使用全局总线在/500页面中接受失败的次数以及是否成功
async error => { const config = error.config; // 重试次数 const retry = config.retry; // 重试时间 const retryDelay = config.retryDelay; // 当前重试次数 config._retryCount = config._retryCount || 0; // 如果重试次数大于定义次数返回错误 if (config._retryCount > retry) { return Promise.reject(new Error(error.response.statusText)); } // 失败后打开到500页面 await router.push('/500'); mittBus.emit('system-request-error', { retry, retryCount: config._retryCount, isSuccess: false }); // 设置请求间隔 在发送下一次请求之前停留一段时间,时间为上方设置好的请求间隔时间 const backoff = new Promise(function (resolve) { setTimeout(() => resolve(true), retryDelay || 1000); }); // 如果失败次数加1 config._retryCount += 1; // 再次发送请求 return backoff.then(() => request(error.config)); }
成功的emit
如果成功使用全局事件总线,在错误页面接受之后跳转
(response: any) => { // 返回消息内容 mittBus.emit('system-request-error', { retry: 0, retryCount: 0, isSuccess: true }); return data; }
错误页
import { HOME_URL } from '@/enums/constant/route.ts'; import { useRouter } from 'vue-router'; import { onMounted, ref } from 'vue'; import mittBus from '@/utils/mittBus.ts'; const router = useRouter(); const retry = ref(import.meta.env.VITE_BASE_API_RETRY); const retryCount = ref(0); const isReTry = ref(false); /** * * 监听失败消息 */ const onListenSystemRequestError = () => { mittBus.on('system-request-error', (value: any) => { if (value.isSuccess) { router.push('/'); // router.go(-1); } retry.value = value.retry; retryCount.value = value.retryCount; if (parseInt(retry.value) === retryCount.value) { isReTry.value = true; } }); }; onMounted(() => { onListenSystemRequestError(); }); @import url('index.scss');
全部Axios代码
import { Message } from '@/components/Message/Message.tsx'; import router from '@/router'; import { localGet, localRemove } from '@/utils/util.ts'; import axios from 'axios'; import mittBus from '@/utils/mittBus.ts'; const request = axios.create({ // 默认请求地址 baseURL: import.meta.env.VITE_BASE_API, // 设置超时时间 timeout: import.meta.env.VITE_BASE_API_TIMEOUT, retry: import.meta.env.VITE_BASE_API_RETRY, //设置全局重试请求次数(最多重试几次请求) retryDelay: import.meta.env.VITE_BASE_API_RETRY_DELAY, //设置全局请求间隔 // 跨域允许携带凭证 // withCredentials: true, }); // 请求拦截器 request.interceptors.request.use(config => { // 当本地有token表示登录了,请求时将token带上 const token = localGet('token'); if (token !== null) { config.headers['token'] = token; } return config; }); // 响应拦截器 request.interceptors.response.use( (response: any) => { // 返回相应数据 const data = response.data; // 登录过期 if (data.code === 208) { Message.warning(data.message); router.push('/').then(); localRemove('token'); } // 账户被封禁 if (data.code === 209) { Message.warning(data.message); router.push('/').then(); localRemove('token'); } // 统一处理异常 if (data.code !== 200 && data.code 300) { Message.error(data.message); } // 返回消息内容 mittBus.emit('system-request-error', { retry: 0, retryCount: 0, isSuccess: true }); return data; }, async error => { const config = error.config; // 重试次数 const retry = config.retry; // 重试时间 const retryDelay = config.retryDelay; // 当前重试次数 config._retryCount = config._retryCount || 0; // 如果重试次数大于定义次数返回错误 if (config._retryCount > retry) { return Promise.reject(new Error(error.response.statusText)); } // 失败后打开到500页面 await router.push('/500'); mittBus.emit('system-request-error', { retry, retryCount: config._retryCount, isSuccess: false }); // 设置请求间隔 在发送下一次请求之前停留一段时间,时间为上方设置好的请求间隔时间 const backoff = new Promise(function (resolve) { setTimeout(() => resolve(true), retryDelay || 1000); }); // 如果失败次数加1 config._retryCount += 1; // 再次发送请求 return backoff.then(() => request(error.config)); }, ); export default request;
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。