1、request.js文件
import axios from 'axios'
import lib from '@/utils/lib'
// 创建 axios 实例
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // api 的 base_url
timeout: 10000
})
lib(service)
export default service
2、lib.js文件
import { Message } from 'element-ui'
import store from '@/store'
import { js2Java, deleteCookie } from '@/utils/tools'
import { osJs2Java } from '@/utils/os/tools'
import { removeToken } from '@/utils/auth'
import { refreshToken } from '@/api/security'
import request from '@/utils/request'
import osRequest from '@/utils/os/request'
let isRefreshing = true // 开关,防止重复请求
// A模式---刷新token的请求函数
async function refreshTokenRequst() {
const ajaxData = {
'accessToken': localStorage.getItem('token'),
'refreshToken': localStorage.getItem('refreshToken'),
'version': 'v1.0',
'seq': 111111
}
const res = await refreshToken(ajaxData)
if (res.data.result.code === '200') {
const resData = res.data.body
if (!resData) {
return
}
const { accessToken, refreshToken } = resData
store.dispatch('setToken', accessToken)
store.dispatch('setFreshToken', refreshToken)
localStorage.setItem('token', accessToken)
localStorage.setItem('refreshToken', refreshToken)
onAccessTokenFetched()
isRefreshing = true
} else {
Message.error(res.data.result.message)
}
}
/**
* B模式---刷新token的请求函数
* token失效 js2Java获取token
* @param {*} ms 定时器时间
* */
function timeout(ms) {
return new Promise((resolve) => {
const params = {
method: 'getRegainOsToken'
}
var token = osJs2Java(params)
if (token !== undefined) {
if (typeof token !== Object) {
token = JSON.parse(token)
}
setTimeout(resolve, ms, token)
}
})
}
/**
* B模式---刷新token的请求函数
* token失效 js2Java获取token
* @param {*} ms 定时器时间
* */
async function getOsToken4(ms) {
const token = await timeout(ms)
if (token) {
store.dispatch('setToken', token.body.accessToken)
localStorage.setItem('token', token.body.accessToken)
onAccessTokenFetched()
isRefreshing = true
} else {
Message.error('获取客户端返回token失败!')
}
}
/**
* 公共部分缓存失效请求
* @param {*} response 缓存接口参数
* @param {*} neighModel 小区模式
*/
function operatePubRequest(response, neighModel) {
// 刷新token的函数,这需要添加一个开关,防止重复请求
if (isRefreshing && neighModel === 2) {
getOsToken4(1000)
}
if (isRefreshing && neighModel === 1) {
refreshTokenRequst()
}
isRefreshing = false
// 这个Promise函数很关键
const retryOriginalRequest = new Promise((resolve) => {
addSubscriber(() => {
const tmpReqData = response.config.data
const isFormData = Object.prototype.toString.call(tmpReqData) === '[object FormData]'
if (response.config.baseURL.lastIndexOf('/res/aa') !== -1) {
resolve(request(
!isFormData ? tmpReqData && JSON.parse(tmpReqData).body
// body有参数
? {
url: response.config.url,
method: response.config.method,
data: JSON.parse(tmpReqData).body
}
// body无参数
: {
url: response.config.url,
method: response.config.method
}
// FormData格式的图片上传
: {
url: response.config.url,
method: response.config.method,
data: tmpReqData
}
))
}
if (response.config.baseURL.lastIndexOf('/res/os') !== -1) {
resolve(osRequest(
tmpReqData && JSON.parse(tmpReqData).body
? {
url: response.config.url,
method: response.config.method,
data: JSON.parse(tmpReqData).body
}
: {
url: response.config.url,
method: response.config.method
}
))
}
})
})
return retryOriginalRequest
}
// Promise函数集合
let subscribers = []
function onAccessTokenFetched() {
subscribers.forEach((callback) => {
callback()
})
subscribers = []
}
function addSubscriber(callback) {
subscribers.push(callback)
}
// request.js公共部分内容
export default function lib(service) {
// 请求拦截器
service.interceptors.request.use(
config => {
const header = {
appName: 'app',
dateTime: new Date().getTime(),
user: 'admin',
language: 'ZH_CN',
serviceName: 'getInfo',
versionId: 'v0.1.1',
token: store.getters.token,
refreshToken: '111b59f3d40a3a9698071a88e3df11fb'
}
const cData = config.data
const isObj = Object.prototype.toString.call(cData) === '[object Object]'
const isFormData = Object.prototype.toString.call(cData) === '[object FormData]'
const isArr = Object.prototype.toString.call(cData) === '[object Array]'
if (isObj && !isArr) {
config.data = {
header: header,
body: {
...cData
}
}
} else if (isFormData) {
// 不用操作
} else {
config.data = {
header: header,
body: cData
}
}
// Do something before request is sent
if (store.getters.token) {
// 让每个请求携带token-- ['Authorization']为自定义key 请根据实际情况自行修改
config.headers['Authorization'] = 'Bearer ' + store.getters.token
// 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
// config.headers['X-Token'] = getToken()
}
return config
},
error => {
// Do something with request error
Promise.reject(error)
}
)
// 响应拦截器
service.interceptors.response.use(
response => {
// 10001=访问令牌过期 重新获取token
// 10002=刷新令牌过期 退出登陆
// 10013=账号已在别处登陆 退出登陆
if (response.data.result !== undefined && (response.data.result.code === '10002' || response.data.result.code === '10013')) {
if (store.getters.neighModel === 2) {
// B模式
return operatePubRequest(response, store.getters.neighModel)
} else {
// A模式
if (document.getElementsByClassName('el-message').length > 0) return
Message.error(response.data.result.message)
setTimeout(() => {
const params = {
method: 'winLogout'
}
js2Java(params)
// 此时后端退出登陆接口报错误码,直接清除缓存,强制刷新退出登陆
store.dispatch('setToken', '')
store.dispatch('setFreshToken', '')
store.dispatch('setNeighNo', '')
// 清除小区号
localStorage.removeItem('neighNo')
localStorage.removeItem('token')
localStorage.removeItem('refreshToken')
localStorage.removeItem('neighModel')
// 清除所有cookie
deleteCookie()
removeToken()
location.reload()
return Promise.reject('error')
}, 1000)
}
} else if (response.data.result !== undefined && response.data.result.code === '10001') {
if (store.getters.neighModel === 2) {
// B模式
return operatePubRequest(response, store.getters.neighModel)
} else {
// A模式
return operatePubRequest(response, store.getters.neighModel)
}
} else {
return response
}
},
error => {
if (error.message === 'Request failed with status code 503') {
Message({
message: '操作失败,请检查服务是否连接正常!',
type: 'error',
duration: 2 * 1000
})
} else if (error.message.toString().indexOf('Network Error') !== -1) {
Message({
message: '网络异常,请检查网络!',
type: 'error',
duration: 2 * 1000
})
} else {
Message({
message: error.message,
type: 'error',
duration: 2 * 1000
})
}
return Promise.reject(error)
}
)
}