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
	}
}
相关推荐
web行路人6 分钟前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
超雄代码狂28 分钟前
ajax关于axios库的运用小案例
前端·javascript·ajax
长弓三石37 分钟前
鸿蒙网络编程系列44-仓颉版HttpRequest上传文件示例
前端·网络·华为·harmonyos·鸿蒙
小马哥编程38 分钟前
【前端基础】CSS基础
前端·css
嚣张农民1 小时前
推荐3个实用的760°全景框架
前端·vue.js·程序员
周亚鑫1 小时前
vue3 pdf base64转成文件流打开
前端·javascript·pdf
Justinc.2 小时前
CSS3新增边框属性(五)
前端·css·css3
neter.asia2 小时前
vue中如何关闭eslint检测?
前端·javascript·vue.js
~甲壳虫2 小时前
说说webpack中常见的Plugin?解决了什么问题?
前端·webpack·node.js
嚣张农民2 小时前
JavaScript中Promise分别有哪些函数?
前端·javascript·面试