- 未登录跳登录页
- 失败重连
- 登录过期跳登录
- 请求之前添加请求头
// utils/require.js
import axios from "axios";
import { showToast } from "vant";
const https = axios.create({
baseURL: "http://47.93.101.203/api/",
timeout: 1000,
});
// 重试次数,共请求2次
https.defaults.retry = 2;
// 请求的间隙
https.defaults.retryDelay = 1000;
// 添加请求拦截器
https.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么
let token =
(JSON.parse(localStorage.getItem("userInfo")) &&
JSON.parse(localStorage.getItem("userInfo")).token) ||
"";
if (token != "") {
config.headers["Authori-zation"] = "Bearer " + token;
}
return config;
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 添加响应拦截器
https.interceptors.response.use(
function (response) {
// 对响应数据做点什么
if (response.data.status == 410000) {
//登录过期跳转登录页
showToast("登录过期请登录");
setTimeout(() => {
location.href = "/login";
}, 500);
}
return response.data;
},
function (error) {
// 对响应错误做点什么
let config = error.config;
// 判断有没有设置重试的次数 没有直接return
if (!config || config.retry) return Promise.reject(error);
// 设置变量以跟踪重连次数
config.__retryCount = config.__retryCount || 0;
// 判断是否大于当前设置的重连次数
if (config.__retryCount>=config.__retry) {
// 返回错误并退出自动重试
return Promise.reject(error);
}
config.__retry+=1
console.log('自动重连'+config.__retry+'次');
var backoff=new Promise(function(resolve){
setTimeout(function () {
resolve()
},config.retryDelay||1000)
})
return backoff.then(function(){
return axios(config)
})
}
);
export default https;
提取重复请求
//utils/failedReconnection.js
export const failedReconnection=(error,axios)=> {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
let config = error.config;
// 如果配置不存在或未设置重试选项,则拒绝
// && 如果前面是false,后面的逻辑就不执行,前面逻辑是true的话就往后执行,只有&& 前面和后面的逻辑都是对的,才能继续。
// || 如果前面逻辑是false的话就走后面,如果前面的逻辑是true的话,就不执行后半部分的代码了。
if (!config || !config.retry) return Promise.reject(error);
// 设置变量以跟踪重试次数
config.__retryCount = config.__retryCount || 0;
// 判断是否超过总重试次数
if (config.__retryCount >= config.retry) {
// 返回错误并退出自动重试
return Promise.reject(error);
}
// 增加重试次数
config.__retryCount += 1;
console.log(config, "config ffff", config.url);
//打印当前重试次数
console.log(config.url + " 自动重试第" + config.__retryCount + "次");
// 创建新的Promise
var backoff = new Promise(function (resolve) {
setTimeout(function () {
resolve();
}, config.retryDelay || 1000);
});
// 返回重试请求
return backoff.then(function () {
return axios(config);
});
}
在utils/require.js中进行修改
import axios from "axios";
import { showToast } from "vant";
import { failedReconnection } from "./failedReconnection";
const https = axios.create({
baseURL: "http://47.93.101.203/api/",
timeout: 1000,
});
// 重试次数,共请求2次
https.defaults.retry = 2;
// 请求的间隙
https.defaults.retryDelay = 1000;
// 添加请求拦截器
https.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么
let token =
(JSON.parse(localStorage.getItem("userInfo")) &&
JSON.parse(localStorage.getItem("userInfo")).token) ||
"";
if (token != "") {
config.headers["Authori-zation"] = "Bearer " + token;
}
return config;
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 添加响应拦截器
https.interceptors.response.use(
function (response) {
// 对响应数据做点什么
if (response.data.status == 410000) {
//登录过期跳转登录页
showToast("登录过期请登录");
setTimeout(() => {
location.href = "/login";
}, 500);
}
return response.data;
},
function (error) {
// 对响应错误做点什么
return failedReconnection(error, https);
}
);
阻止重复请求,取消请求
//修改utils/request.js
import axios from "axios";
import { showToast } from "vant";
import { failedReconnection } from "./failedReconnection";
const https = axios.create({
baseURL: "http://47.93.101.203/api/",
timeout: 1000,
});
//请求列表
let reqList = [];
// 重试次数,共请求2次
https.defaults.retry = 2;
// 请求的间隙
https.defaults.retryDelay = 1000;
// 添加请求拦截器
https.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么
let token =
(JSON.parse(localStorage.getItem("userInfo")) &&
JSON.parse(localStorage.getItem("userInfo")).token) ||
"";
if (token != "") {
config.headers["Authori-zation"] = "Bearer " + token;
}
config.cancelToken = new axios.CancelToken(function (c) {
cancel = c;
});
stopRepeatRequest(reqList, config.url, cancel, `${config.url} 请求被中断`)
return config;
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 添加响应拦截器
https.interceptors.response.use(
function (response) {
// 对响应数据做点什么
if (response.data.status == 410000) {
//登录过期跳转登录页
showToast("登录过期请登录");
setTimeout(() => {
location.href = "/login";
}, 500);
}
return response.data;
},
function (error) {
// 对响应错误做点什么
// 增加延迟,相同请求不得在短时间内重复发送
setTimeout(() => {
allowRequest(reqList, error.config.url);
}, 2000);
return failedReconnection(error, https);
}
);
/**
* 阻止重复请求
* @param {array} reqList - 请求缓存列表
* @param {string} url - 当前请求地址
* @param {function} cancel - 请求中断函数
* @param {string} errorMessage - 请求中断时需要显示的错误信息
*/
const stopRepeatRequest = function (reqList, url, cancel, errorMessage) {
const errorMsg = errorMessage || "";
for (let i = 0; i < reqList.length; i++) {
if (reqList[i] === url) {
cancel(errorMsg);
return;
}
}
reqList.push(url);
};
/**
* 允许某个请求可以继续进行
* @param {array} reqList 全部请求列表
* @param {string} url 请求地址
*/
const allowRequest = function (reqList, url) {
for (let i = 0; i < reqList.length; i++) {
if (reqList[i] === url) {
reqList.splice(i, 1);
break;
}
}
};
export default https;
提取 取消重复请求方法
//utils/stopRepeatRequest.js
export let reqList = [];
/**
* 阻止重复请求
* @param {array} reqList - 请求缓存列表
* @param {string} url - 当前请求地址
* @param {function} cancel - 请求中断函数
* @param {string} errorMessage - 请求中断时需要显示的错误信息
*/
export const stopRepeatRequest = function (reqList, url, cancel, errorMessage) {
const errorMsg = errorMessage || "";
for (let i = 0; i < reqList.length; i++) {
if (reqList[i] === url) {
cancel(errorMsg);
return;
}
}
reqList.push(url);
};
/**
* 允许某个请求可以继续进行
* @param {array} reqList 全部请求列表
* @param {string} url 请求地址
*/
export const allowRequest = function (reqList, url) {
for (let i = 0; i < reqList.length; i++) {
if (reqList[i] === url) {
reqList.splice(i, 1);
break;
}
}
};
修改utils/require.js
import axios from "axios";
import { showToast } from "vant";
import { failedReconnection } from "./failedReconnection";
import { reqList, stopRepeatRequest, allowRequest,} from "./stopRepeatRequest.js";
const https = axios.create({
baseURL: "http://47.93.101.203/api/",
timeout: 1000,
});
//请求列表
// 重试次数,共请求2次
https.defaults.retry = 2;
// 请求的间隙
https.defaults.retryDelay = 1000;
// 添加请求拦截器
https.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么
let token =
(JSON.parse(localStorage.getItem("userInfo")) &&
JSON.parse(localStorage.getItem("userInfo")).token) ||
"";
if (token != "") {
config.headers["Authori-zation"] = "Bearer " + token;
}
config.cancelToken = new axios.CancelToken(function (c) {
cancel = c;
});
stopRepeatRequest(reqList, config.url, cancel, `${config.url} 请求被中断`)
return config;
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 添加响应拦截器
https.interceptors.response.use(
function (response) {
// 对响应数据做点什么
if (response.data.status == 410000) {
//登录过期跳转登录页
showToast("登录过期请登录");
setTimeout(() => {
location.href = "/login";
}, 500);
}
return response.data;
},
function (error) {
// 对响应错误做点什么
// 增加延迟,相同请求不得在短时间内重复发送
setTimeout(() => {
allowRequest(reqList, error.config.url);
}, 2000);
return failedReconnection(error, https);
}
);
提取拦截器
//utils/interceptors.js
import { failedReconnection } from "./failedReconnection";
import {
reqList,
stopRepeatRequest,
allowRequest,
} from "./stopRepeatRequest.js";
import request from "./request.js";
let { instance, axios } = request;
let time = 1000;
// 添加请求拦截器
instance.interceptors.request.use(
function (config) {
console.log(config.retryDelay, "config.retryDelay");
if (config.retryDelay < time) {
config.retryDelay = time + 500;
}
// 在发送请求之前做些什么
let cancel;
// 设置cancelToken对象
config.cancelToken = new axios.CancelToken(function (c) {
cancel = c;
});
// 阻止重复请求。当上个请求未完成时,相同的请求不会进行
stopRepeatRequest(reqList, config.url, cancel, `${config.url} 请求被中断`);
return config;
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 添加响应拦截器
instance.interceptors.response.use(
function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
setTimeout(() => {
allowRequest(reqList, response.config.url);
}, time);
let { data } = response;
return data;
},
function (error) {
if (axios.isCancel(error)) {
return Promise.reject(error.message);
}
// 增加延迟,相同请求不得在短时间内重复发送
setTimeout(() => {
allowRequest(reqList, error.config.url);
}, time);
return failedReconnection(error, instance);
}
);
export default instance;
修改utils/require.js
import axios from "axios";
let baseURL = import.meta.env.VITE_BSEL_URL;
const instance = axios.create({
baseURL,
});
// 重试次数,共请求2次
instance.defaults.retry = 2;
// 请求的间隙
instance.defaults.retryDelay = 1000;
export default { instance, axios };