Nuxt2 接口请求失败重新发送请求

遇到一个需求,要求只要接口请求不成功就重试一次。

Nuxt.js 2.x ,在 ~/plugins/axios.js 文件中使用 Axios 的拦截器功能来实现请求失败时重新发送请求的逻辑:

~/plugins/axios.js 文件中定义重试逻辑:

javascript 复制代码
import axios from 'axios';
 
// 创建一个axios实例
const axiosInstance = axios.create();
 
// 请求拦截器
axiosInstance.interceptors.request.use(config => {
  // 可以在这里添加配置信息
  return config;
}, error => {
  // 请求错误时的处理
  return Promise.reject(error);
});
 
// 响应拦截器
axiosInstance.interceptors.response.use(response => {
  // 请求成功的处理
  return response;
}, error => {
  // 请求失败时的处理,并决定是否重发请求
  const config = error.config;
  // 如果配置中设置了不重发,或者已经是重发了,直接抛出错误
  if(!config || !config.retry) return Promise.reject(error);
  
  // 重发请求的次数
  config.retryCount = config.retryCount || 0;
  
  // 检查是否超过最大重发次数
  if(config.retryCount >= config.retry) {
    return Promise.reject(error);
  }
  
  // 增加重发次数
  config.retryCount++;
  
  // 延迟一段时间后重发请求
  const backoff = new Promise(resolve => {
    setTimeout(() => resolve(), config.retryDelay || 1);
  });
  
  // 返回重发的Promise
  return backoff.then(() => axiosInstance(config));
});
 
export default axiosInstance;

nuxt.config.js 文件中配置插件:

arduino 复制代码
export default {
  // ...
  plugins: [
    '@/plugins/axios'
  ],
  // ...
}

使用(这里是单独设置接口的重新发送请求):

arduino 复制代码
axios.post('/api/...', {
    retry: 2, // 最大重试次数
    retryDelay: 500  // 重试间隔时间/毫秒
})

我的实际项目中是直接在全局设置的,这样就不需要每个接口去设置了:

typescript 复制代码
import { Context } from '@nuxt/types';
import axios,{ AxiosResponse, AxiosRequestConfig, AxiosError } from 'axios';

// 创建一个axios实例
const axiosInstance = axios.create()

export default async function (ctx: Context) {
  const $axios:any = ctx.app.$axios;
  $axios.defaults.withCredentials = false; // 默认不携带cookie
  $axios.defaults.timeout = 30 * 1000; // 超时 30 * 1000
  // 请求失败重新发起请求
  $axios.defaults.retry = 2 // 最大重发请求次数
  $axios.defaults.retryCount = 0 // 已重发请求次数
  $axios.defaults.retryDelay = 500 // 重新请求间隔时间


  $axios.onRequest((config: AxiosRequestConfig) => {
    const token: string = ctx.app.$cookies.get('access_token');
    if (token && config.headers.common) {
      config.headers.common.Authorization = token;
    }
    return config;
  });


  $axios.onResponse((response: AxiosResponse<any>): any => {
    const { config, status } = response;
    ...
    return response.data;
  });

  $axios.onError((error: AxiosError<any>) => {
    const { status, config } = (error.response as any) || {};
    console.log('error-config', error.config)
    // 接口请求失败重新发起请求
    if (config.retry && config.retryCount < config.retry) {
      console.log("axios重新发送请求")
      // 延迟一段时间后重发请求
      const backoff = new Promise(resolve => {
        setTimeout(() => resolve(""), config.retryDelay || 1);
      });
      config.retryCount++
      // 返回重发的Promise
      return backoff.then(() => axiosInstance(config))
    }
    
    return Promise.resolve({
      code: '0',
      message: 'API Error',
      data: null,
    });
  });
}

console.log('error-config', error.config) 输出:

json 复制代码
{
	"url": "/api/你的接口地址",
	"method": "post",
	"data": "{}",
	"headers": {
		"Accept": "application/json, text/plain, */*",
		"Authorization": "",
		"DEVICE": "pc",
		"Content-Type": "application/json;charset=utf-8"
	},
	"baseURL": "/",
	"transformRequest": [null],
	"transformResponse": [null],
	"timeout": 30000,
	"withCredentials": false,
	"xsrfCookieName": "XSRF-TOKEN",
	"xsrfHeaderName": "X-XSRF-TOKEN",
	"maxContentLength": -1,
	"maxBodyLength": -1,
	"retry": 2, // 重试次数
	"retryCount": 0,
	"retryDelay": 500,
	"axios-retry": {
		"retryCount": 0,
		"lastRequestTime": 1710836764162
	}
}
相关推荐
轻口味1 小时前
【每日学点鸿蒙知识】AVCodec、SmartPerf工具、web组件加载、监听键盘的显示隐藏、Asset Store Kit
前端·华为·harmonyos
alikami1 小时前
【若依】用 post 请求传 json 格式的数据下载文件
前端·javascript·json
吃杠碰小鸡2 小时前
lodash常用函数
前端·javascript
emoji1111112 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
泰伦闲鱼2 小时前
nestjs:GET REQUEST 缓存问题
服务器·前端·缓存·node.js·nestjs
m0_748250032 小时前
Web 第一次作业 初探html 使用VSCode工具开发
前端·html
一个处女座的程序猿O(∩_∩)O2 小时前
vue3 如何使用 mounted
前端·javascript·vue.js
m0_748235952 小时前
web复习(三)
前端
AiFlutter2 小时前
Flutter-底部分享弹窗(showModalBottomSheet)
java·前端·flutter
麦兜*2 小时前
轮播图带详情插件、uniApp插件
前端·javascript·uni-app·vue