axios-retry 响应异常

最近项目中遇到 axios 异步请求异常中断, 错误码为 "ECONNABORTED"

奇怪的是排查前端代码并没有发现有主动调用 abort 取消请求的

由于为何网络请求失败的原因找不到, 但是重试请求就是成功的, 所以计划使用 axios-retry 在网络错误时重新请求

javascript 复制代码
import axiosRetry from 'axios-retry'
import axios from 'axios'

const service = axios.create({
	// .... 各种配置项
})

axiosRetry(service, {
	retries: 1,  // 重新请求次数, 这里由于只是为了解决特殊情况下的网络错误, 所以只重试一次即可
	// 重试条件
	retryCondition: error => {
    	return error.code === 'ECONNABORTED' // 仅这个错误下重试请求
	}
})

使用以上方案后, 解决了网络错误下接口失败的问题, 但是发现在重试请求成功后, js 代码里拿到的结果不对

经过排查, 发现 axios-retry 虽然能重新请求, 但是会基于实际请求次数多次调用 interceptors 拦截器的钩子

拦截器代码

javascript 复制代码
service.interceptors.response.use(
	response => {
		return response.data
	},
	error => {
		ElMessage({
			message: error.message,
			type: 'error',
			duration: 3000
		})
	}
)

拦截器钩子第二次执行时返回的实际上是 response.data.data, 这会导致外部调用者拿不到预期结果 但这是 axios 或 axios-retry 内部的问题, 我们无法解决, 所以只能在钩子里做判断, 如果当前请求已经进入过拦截器处理, 就直接退出

拦截器做调整

javascript 复制代码
service.interceptors.response.use(
	response => {
		// 如果之前进入过拦截器钩子, 那么 response 实际上就已经是 response.data, 直接 return
		if(!(response.request instanceof XMLHttpRequest)){
			return response
		}
		return response.data
	},
	// 错误处理加入防抖, 同样的 error 只执行一次回调
	throttleErrorCallback(error => {
		ElMessage({
			message: error.message,
			type: 'error',
			duration: 3000
		})
	})
)

// 错误处理防抖
function throttleErrorCallback(callback){
	const handledErrors = new WeakSet()
	return error => {
		if(handledErrors.has(error) {
			return Promise.reject(error)
		}
		handledErrors.add(error)
		return callback(error)
	}
}

如果有其他解决 axios-retry 带来的拦截器问题的方式, 欢迎交流

相关推荐
IT乐手15 分钟前
Claude Code + Qwen 的配置方法
javascript·claude
子兮曰2 小时前
DeepSeek TUI:原生 Rust 打造的终端 AI 编码 Agent
前端·javascript·后端
暗不需求2 小时前
# 深入 React Todos:从零实现一个状态提升与本地持久化的待办应用
javascript·react.js·全栈
子兮曰2 小时前
深入 Superpowers:180k Stars 的开源 AI 编程方法论是如何工作的
前端·javascript·后端
隔壁的大叔3 小时前
Markdown 渲染如何穿插自定义组件
前端·javascript·vue.js
薯老板3 小时前
JavaScript原型,原型链
javascript
愚者Pro3 小时前
Flutter基础学习
前端·javascript·vue.js
时光足迹4 小时前
Tiptap 简单编辑器模版
前端·javascript·react.js
吴声子夜歌4 小时前
Vue3——使用Mock.js
javascript·vue·mock.js
时光足迹4 小时前
ThreeJS之GUI控制器
前端·javascript·three.js