vue封装 request.js
import axios from 'axios'import {VueAxios} from './axios'import notification from 'ant-design-vue/es/notification'import store from '@/store'import router from '../router'import {setToken,getToken,get
·
import axios from 'axios'
import {
VueAxios
} from './axios'
import notification from 'ant-design-vue/es/notification'
import store from '@/store'
import router from '../router'
import {
setToken,
getToken,
getRefreshToken,
setRefreshToken
} from '@/utils/auth'
import qs from 'qs'
// 是否正在刷新的标记
let isRefreshing = false
// 重试队列,每一项将是一个待执行的函数形式
let retryRequests = []
// 创建axios实例
const service = axios.create({
baseURL: process.env.BASE_API, // api的base_url
timeout: 100000 // 请求超时时间
})
// 设置缓存时间 和缓存请求数组
var requestUrl = []
const saveTime = 500
// request拦截器
service.interceptors.request.use(
config => {
const sessitionToken = getToken()
if (store.getters.token || sessitionToken) {
const token = store.getters.token || sessitionToken
config.headers.common['Authorization'] = 'Bearer ' + token // 让每个请求携带自定义token
}
if (
config.method === 'post' ||
config.method === 'put' ||
config.method === 'delete'
) {
// 筛选在缓存时间内未过期请求 重新赋值缓存请求数组 新数组与当前请求url 匹配
// 如果有相等项 则判断为重复提交的请求 直接return
const nowTime = new Date().getTime()
requestUrl = requestUrl.filter(item => {
return item.setTime + saveTime > nowTime
})
const sessionUrl = requestUrl.filter(item => {
return item.url === config.url
})
if (sessionUrl.length > 0) {
notification.error({
message: '错误',
description: '操作太快了,请稍等!'
})
}
const item = {
url: config.url,
setTime: new Date().getTime()
}
requestUrl.push(item)
}
return config
},
error => {
// Do something with request error
Promise.reject(error)
}
)
// respone拦截器
service.interceptors.response.use(
response => {
// 如果不是2000000直接return 返回状态码以及错误信息 response.data.code !== 2000100 &&
if (
response.data &&
response.data.code !== 2000000 &&
response.data.code &&
typeof response.data.code === 'number'
) {
notification.error({
message: '错误',
description: '信息:' + response.data.message || response.message
})
return response.data
}
// 402:非法的token; 50012:其他客户端登录了; 50014:Token 过期了
if (response.code === 401 || response.code === 4010200) {
// 请自行在引入 MessageBox
// import { Message, MessageBox } from 'element-ui'
// MessageBox.confirm(
// '你已被登出,可以取消继续留在该页面,或者重新登录',
// '确定登出', {
// confirmButtonText: '重新登录',
// cancelButtonText: '取消',
// type: 'warning'
// }
// ).then(() => {
// store.dispatch('FedLogOut1').then(() => {
// location.reload() // 为了重新实例化vue-router对象 避免bug
// })
// })
}
return response.data
},
error => {
if (error.response) {
const response = error.response.data
if (response.code === 4010200) {
const config = error.response.config
if (!isRefreshing) {
isRefreshing = true
return getRefreshTokenFunc()
.then((res) => {
// 重新设置token
setToken(res.data.access_token)
setRefreshToken(res.data.refresh_token)
store.commit('SET_TOKEN', res.data.access_token)
config.headers.Authorization = 'Bearer ' + res.data.access_token
// 已经刷新了token,将所有队列中的请求进行重试
// @ts-ignore
retryRequests.forEach((cb) => cb(res.data.access_token))
// 重试完清空这个队列
retryRequests = []
// 这边不需要baseURL是因为会重新请求url,url中已经包含baseURL的部分了
config.baseURL = ''
return service.request(config)
})
.catch(() => {
resetLogin()
})
.finally(() => {
isRefreshing = false
})
} else {
// 正在刷新token,返回一个未执行resolve的promise
return new Promise((resolve) => {
// 将resolve放进队列,用一个函数形式来保存,等token刷新后直接执行
// @ts-ignore
retryRequests.push((token) => {
config.baseURL = ''
config.headers.Authorization = 'Bearer ' + token
resolve(service.request(config))
})
})
}
} else {
notification.error({
message: '错误',
description: '信息:' + response.message
})
}
} else {
const errMsg = error.toString()
notification.error({
message: '错误',
description: errMsg
})
}
return Promise.reject(error)
}
)
// 刷新token的请求方法
function getRefreshTokenFunc() {
var grantType = 'refresh_token'
var clientId = 'erp'
var clientSecret = 'cloud'
var params = qs.stringify({
refresh_token: getRefreshToken(),
client_id: clientId,
client_secret: clientSecret,
grant_type: grantType
})
return axios.post(process.env.BASE_API + '/oauth/token', params)
}
function resetLogin() {
store.dispatch('FedLogOut1').then(() => {
router.push({
name: 'login'
})
location.reload() // 为了重新实例化vue-router对象 避免bug
})
}
const installer = {
vm: {},
install(Vue) {
Vue.use(VueAxios, service)
}
}
export default service
export {
installer as VueAxios,
service as axios
}
更多推荐
已为社区贡献1条内容
所有评论(0)