1.axios的二次封装
import axios from 'axios'
import { Message } from 'element-ui'
const http = axios.create({
baseURL: '/api', // 在vue.config.js 配置跨域
timeout: 5000 ,
withCredentials: false // 表示跨域请求时是否需要使用凭证
})
// 请求拦截器
http.interceptors.request.use(
config => {
return config
},
error => {
// do something with request error
console.log(error)
return Promise.reject(error)
}
)
// 响应拦截器
http.interceptors.response.use(
response => {
return response.data
},
error => {
console.log('err' + error)
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default http
复制代码
进行跨域配置
1.我们需要找到vue.config.js文件,编写解决跨域的代码,文件的代码如下
module.exports = {
lintOnSave: false, //关闭eslint检查
devServer: {
open: true,
// 解决代理跨域问题
proxy: {
'/api': {
target: 'xxx',
pathRewrite: { '^/api': '' },
changeOrigin: true // 允许跨域
}
}
}
}
复制代码
2.axios的错误重复请求
import axios from 'axios'
// 重试次数,共请求2次
axios.defaults.retry = 1
// 请求的间隙
axios.defaults.retryDelay = 1000
axios.interceptors.response.use(undefined, function axiosRetryInterceptor(err) {
// 发送请求后返回错误状态码的那个接口的请求配置,都存在宇err.config里面
let config = err.config;
// 如果配置不存在或未设置重试选项,则拒绝
// 重试请求的次数,如果你设置了1,就请求2次,如果是5,就请求6次
if (!config || !config.retry) return Promise.reject(err);
// 设置变量以跟踪重试次数
config.__retryCount = config.__retryCount || 0;
// 判断是否超过总重试次数,超过retry设置的次数的时候,就不再重复发起请求了
if (config.__retryCount >= config.retry) {
// 返回错误并退出自动重试
return Promise.reject(err);
}
// 增加重试次数
config.__retryCount += 1;
//打印当前重试次数
console.log(config.url + ' 自动重试第' + config.__retryCount + '次');
// 创建新的Promise
let backoff = new Promise(function (resolve) {
setTimeout(function () {
resolve();
}, config.retryDelay || 1);
});
// 返回重试请求
return backoff.then(function () {
return axios(config);
});
});
export default axios;
复制代码
3.axios防止重复请求 优化
import axios from "axios";
const http = axios.create({
baseURL: process.env.VUE_APP_BASE_URL,//公共路径
});
//取消请求
let httplist = []
const removeHttp = config => {
let index = httplist.findIndex(v => v.url === config.url && v.method === config.method)
if (index >= 0) {
//取消请求
httplist[index].controller.abort()
//删除当前数据
httplist.splice(index, 1)
}
}
http.interceptors.request.use(
function (config) {
removeHttp(config)
//取消操作
//在push之前遍历数组找到相同的请求取消掉
const controller = new AbortController()
config.signal = controller.signal //用来取消操作的key
config.controller = controller //将控制器绑定到每个请求身上
httplist.push({ ...config }) //每次的请求加入到数组
return config
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error)
}
)
// 添加响应拦截器
http.interceptors.response.use(
function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
const { data } = response;
return data;
},
function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
}
);
复制代码
4.token失效返回登录页面
实现方式: 在路由文件router/index.js文件下面的登录路由中添加一个对公的条件,然后在beforeEach钩子函数中添加条件判断条件:
// 登录的路由中添加对公的条件
{
path: "/",
redirect: "/login",
},{
path: "/login",
name: "login",
component: () => import("../views/login"),
meta: { isPublic: true },
},...
// 按照路由是否公开,来处理路由的动作
router.beforeEach((to, from, next) => {
//如果不是可公开的路由并且当前没有token,那么要跳转到登陆页
if (!to.meta.isPublic && !sessionStorage.getItem("token")) {
next("/");
}
next();
});