取消重复请求
使用情况:当网速太慢,请求速度变慢,但却又进行请求,会浪费性能,所以为了解决这个问题,axios有个属性可以解决。
AbortController
从 v0.22.0 开始,Axios 支持以 fetch API 方式—— AbortController 取消请求:
const controller = new AbortController();
axios.get('/foo/bar', { signal: controller.signal }).then(function(response) {
//...
});
// 取消请求
controller.abort()
CancelToken deprecated
您还可以使用 cancel token 取消一个请求。
Axios 的 cancel token API 是基于被撤销 cancelable promises proposal。
此 API 从
v0.22.0开始已被弃用,不应在新项目中使用。
可以使用 CancelToken.source 工厂方法创建一个 cancel token ,如下所示:
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345',{
cancelToken: source.token
}).catch(function (thrown) {
if (axios.isCancel(thrown)){
console.log('Request canceled', thrown.message);
}else {
// 处理错误 }
});
axios.post('/user/12345', {
name: 'new name'
}, {
cancelToken: source.token
})
// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');
也可以在请求拦截器的时候添加
// 请求的间隙
axios.defaults.retryDelay = 1000;
const pending = [];
//取消请求的函数
const removePending = (config) => {
let pendingIndex = pending.findIndex((v) => {
//判断config里面的内容是否是上一次请求的接口
if (
config.url === v.url &&
config.method === v.method &&
JSON.stringify(config.params) === JSON.stringify(v.params) &&
JSON.stringify(config.body) === JSON.stringify(v.body)
) {
v.controller.abort();
return true;
}
return false;
});
if (pendingIndex >= 0) {
pending.splice(pendingIndex, 1);
}
};
axios.interceptors.request.use(function (config){
// 取消重复请求
removePending(config);
const controller = new AbortController();
config.signal = controller.signal;
config.controller = controller;
pending.push({ ...config });
return config;
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}
);
token失效跳转到登录页面
在路由页面定义
//定义一个时间
let time=30000
//router. beforeEach 是全局钩子函数,它是在路由跳转之前所调用的函数,在实际开发中页面进度条的加载、设置页面标题、判断用户是否已经登录过了等等都可以在该函数中执行。
router.beforeEach((to, from, next) => {
//把转化为字符串的本地取出来 并转换回来
let token=JSON.parse(localStorage.getItem('token'))
//如果本地有数据
if(token){
//获取当前时间
let newtime=new Date().getTime()
// 当前时间减去存储时间是否大于30000毫秒
if(newtime-token.time>time){
// 如果大于清楚本地存储并跳转登录
localStorage.removeItem('token')
next('/')
}else{
}
}else{
//如果没有数据返回登录页面
if(to.path=="/"){
next()
}else{
alert('请先登录,在访问其他页面')
next('/')
}
}
})
在axios响应拦截器定义
import router from "@/router";
axios.interceptors.response.use(
function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
let { data } = response;
//token失效请求接口的时候的返回值=410000
if(data.status===410000){
router.replace('/login')
}
return data;
},
function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
}
);
接口请求失败重新请求
// 重试次数,共请求2次
axios.defaults.retry = 1;
// 添加请求拦截器
axios.interceptors.response.use(undefined, function axiosRetryInterceptor(err) {
var config = err.config;
// 如果配置不存在或未设置重试选项,则拒绝
if (!config || !config.retry) return Promise.reject(err);
// 设置变量以跟踪重试次数
config.__retryCount = config.__retryCount || 0;
// 判断是否超过总重试次数
if (config.__retryCount >= config.retry) {
// 返回错误并退出自动重试
return Promise.reject(err);
}
// 增加重试次数
config.__retryCount += 1;
//打印当前重试次数
console.log(config.url + " 自动重试第" + config.__retryCount + "次");
// 创建新的Promise
var backoff = new Promise(function (resolve) {
setTimeout(function () {
resolve();
}, config.retryDelay || 1);
});
// 返回重试请求
return backoff.then(function () {
return axios(config);
});
});