前言
对于接口拦截的使用场景我们一般是在一些组件切换的时候,虽然组件被销毁,但是往往这个时候内部没有完成的接口请求以及异步任务已经被推入了异步队列,其回调依旧会被代码执行完毕,所以就会导致当你路由或者组件切换的时候一些接口任然被执行。🦐
比如我们在写地图大屏的时候,我们的路由以及组件切换并不会让地图组件切换,也就是地图组件是一直存在的。⛽️如果我们切换到一个页面请求接口会渲染一些点位,但是如果这个时候接口比较慢,我们又很快的切换到了其他页面,这个时候vue组件虽然被销毁,我们也在beforeDestroy的时候清除了地图点位,但是里面的异步任务已经被推入了执行队列,并不会被销毁,那上一个页面的地图点位就很容易无法被清除而带到了我们当前的页面来,这是一个很棘手的问题,这个时候就需要引入我们的axios的接口拦截功能了🐛。
技术栈
axios,vue2,vue3,TS,pinia
1.实现路由切换统一接口拦截
技术栈:vue2 JS
💰我们先来实现一个比较简单的接口拦截全局控制方法,也就是在我们路由切换的时候实现全部接口的拦截,因为我们一般的应用场景只是会在路由切换的时候需要用到接口拦截功能。
axios请求拦截方法
import axios from 'axios'
let axiosCancel = ''
/**
* @description 基于axios的二次封装
*/
const Instance = axios.create({
timeout: 60 * 1000
})
/**
* 请求拦截
*/
Instance.interceptors.request.use(
config=> {
const CancelToken = axios.CancelToken
const source = CancelToken.source()
config.cancelToken = source.token // 将token注入到请求中
axiosCancel = source
return config
}
)
我们在axios
的接口请求拦截里面将取消接口token注入到请求中去并赋值给了我们定义的变量axiosCancel
,这样我们只需要调用axiosCancel
的cancel
方法就可以实现接口的拦截
axiosCancel.cancel('取消了接口‘)
👀这边注意到我们在使用cancel
的时候还传入了字符串,此字符串也会被我们axios
的响应拦截所拦截,并会跳入error
,也就是被try...carch
捕获,这样我们就可以通过判断message
的名称来知道此接口异常的原因是被接口拦截了,也可以通过axios提供的isCancel方法判断是否是请求接口拦截,那我们一般会封装此情况的接口不会在界面出现错误提示 🥺
/**
* 接口响应拦截
*/
Instance.interceptors.response.use(
response => {
....省略此处代码
},
error => {
// if (error.message !== '取消了请求') {
if(!axios.isCancel(error))
Message.error({
message: '服务异常,请稍后再试' })
}
return Promise.reject(error)
}
)
实现路由切换拦截所有接口
现在我们😯只需要将这个装有拦截token的变量注入到我们任何想拦截他的地方就可以了,我们可以将它赋值给window对象,也可以赋值给vuex变量都可以。以下以window对象为例🌰
Instance.interceptors.request.use(
config=> {
!window.axiosCancel && (window.axiosCancel = [])
const CancelToken = axios.CancelToken
const source = CancelToken.source()
config.cancelToken = source.token // 将token注入到请求中
window.axiosCancel.push(source)
return config
}
)
再配置一下我们的路由守卫,判断如果是初始化也就是’/'地址,那么就设置window.axiosCancel = []
,🀄️在路由切换的时候将所有的接口都遍历拦截即可:
const router = new