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
	}
}
相关推荐
陈天伟教授16 小时前
人工智能训练师认证教程(2)Python os入门教程
前端·数据库·python
信看17 小时前
NMEA-GNSS-RTK 定位html小工具
前端·javascript·html
Tony Bai17 小时前
【API 设计之道】04 字段掩码模式:让前端决定后端返回什么
前端
苏打水com18 小时前
第十四篇:Day40-42 前端架构设计入门——从“功能实现”到“架构思维”(对标职场“大型项目架构”需求)
前端·架构
king王一帅18 小时前
流式渲染 Incremark、ant-design-x markdown、streammarkdown-vue 全流程方案对比
前端·javascript·人工智能
苏打水com18 小时前
第十八篇:Day52-54 前端跨端开发进阶——从“多端适配”到“跨端统一”(对标职场“全栈化”需求)
前端
Bigger18 小时前
后端拒写接口?前端硬核自救:纯前端实现静态资源下载全链路解析
前端·浏览器·vite
BD_Marathon18 小时前
【JavaWeb】路径问题_前端绝对路径问题
前端
whyfail19 小时前
Vue原理(暴力版)
前端·vue.js