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 带来的拦截器问题的方式, 欢迎交流

相关推荐
PYB32 小时前
【Web·JS·基础】函数的使用和展运算符...objs
前端·javascript
默_笙3 小时前
🚥 给 RAG 装一台心电监护仪:LangSmith 全链路观测(上)
前端·javascript
变与不变8065 小时前
js同步和异步难点重点详解
开发语言·javascript·ecmascript
Dovis(誓平步青云)5 小时前
多个链接不等于多份证据,新闻核验看板怎样合并来源
java·服务器·前端·javascript·人工智能·pdf·电脑
Dovis(誓平步青云)6 小时前
几个方案来回选不定?做一个随时切换的候选推荐页
android·java·服务器·开发语言·javascript·数据库·智能化
可乐鸡翅yeah_7 小时前
fmp4 碎片 MP4 格式 HLS 流,和传统 TS 分片有什么不一样
开发语言·javascript·ios·音视频·safari·m3u8·m3u8在线播放
ss2738 小时前
AI全栈实战 | 2.3-01 组件库实战:Element Plus 怎么搭出专业界面,过度封装为什么成维护负担
前端·javascript·elementui·vue
福兮说9 小时前
URL 编码的七个坑:c++ 传到后端变空格、%25 套娃、截断 emoji 直接报错
开发语言·前端·javascript·node.js·url
小的时候可菜了9 小时前
JS 异步的本质:从单线程到 thenable(一条进化链)
开发语言·前端·javascript
可乐鸡翅yeah_9 小时前
hls.js 配置 loadStartPosition,点播起始播放位置踩坑
开发语言·javascript·网络协议·ecmascript·m3u8在线