import axios from 'axios' import {Message} from 'element-ui' import $store from '@/store' import store from '@/store/login' import router from '@/router/router.js' import NProgress from 'nprogress' import 'nprogress/nprogress.css' import {saveAs} from 'file-saver' axios.defaults.timeout = 100000 let pending = [] //声明一个数组用于存储每个ajax请求的取消函数和ajax标识 let cancelToken = axios.CancelToken let removePending = ever => { for (let p in pending) { if ( pending[p].u === ever.url + '&' + ever.method && pending[p].data === eval.data ) { //当当前请求在数组中存在时执行函数体 pending[p].f() //执行取消操作 pending.splice(p, 1) //把这条记录从数组中移除 } } } // 请求拦截(配置发送请求的信息) axios.interceptors.request.use( config => { // 处理请求之前的配置 NProgress.start() //开始 store.state.loadding = true //在请求发出之前进行一些操作 config.headers = config.headers || {} if (config.headers && config.headers.constructor === String) { try { config.headers = JSON.parse(config.headers) } catch (e) { Message.error(`请求头部不是有效的JSON格式:${config.headers}`) throw e } } config.headers['Cross-Origin-Embedder-Policy'] = 'require-corp' config.headers['Cross-Origin-Opener-Policy'] = 'same-origin' config.headers['Accept-Language'] = localStorage.getItem('lang') || 'zh-CN' if (store.state.loginAccount) { config.headers['Tenant-Code'] = localStorage .getItem(store.state.loginAccount + 'loginRoutePath') .replace('/login/', '') || '' } const currentUser = store.state.currentUser currentUser && currentUser.token && !config.headers.Authorization && (config.headers.Authorization = `Bearer ${currentUser.token}`) //如果是请求auth接口,则不带token if (config.url.indexOf('/auth?') !== -1) { delete config.headers.Authorization } removePending(config) //在一个ajax发送前执行一下取消操作 config.cancelToken = new cancelToken(c => { // 将请求的地址和请求的方式构建为一个字符串存放到请求数组中 pending.push({ u: config.url + '&' + config.method, f: c, data: config.data }) }) // 判断是否需要刷新token let currentTime = new Date().getTime() if ( currentUser && currentUser.loginTime && currentTime - currentUser.loginTime >= (currentUser.expiration / 5) * 1000 && config.url.indexOf('/refresh') == -1 ) { $store.dispatch('login/refreshAndGetAuthenticationToken') } return config }, error => { // 请求失败的处理 NProgress.done() // 结束 return Promise.reject(error) } ) // 响应拦截(配置请求回来的信息) axios.interceptors.response.use( res => { // 是否显示错误信息,默认为显示 const isShowMessage = res.config.isShowMessage !== undefined ? res.config.isShowMessage : true // 取消已完成的请求 removePending(res.config) // 处理错误信息 if (res.data?.state === false && isShowMessage) { Message.errorLog(res.data.message, res.data.logId) } // 更新加载状态 store.state.loadding = false // 结束进度条 NProgress.done() // 处理附件下载 if ( res.status === 200 && res.headers?.['content-disposition']?.startsWith('attachment;') ) { const blob = new Blob([res.data]) const fileName = decodeURIComponent( res.headers['content-disposition'].split(';')[1].split('filename=')[1] ) saveAs(blob, fileName) } return res }, error => { // 判断是否是取消请求导致的错误 if (axios.isCancel(error)) { NProgress.done() // 结束 return Promise.reject(error) } // 处理其他类型的错误 let errorMessage, // 错误响应消息 bufferErrorResponse // 错误响应体 if (error?.response?.data instanceof ArrayBuffer) { // 使用 TextDecoder 将 ArrayBuffer 转换为字符串 const decoder = new TextDecoder('utf-8') const decodedString = decoder.decode(new Uint8Array(error.response.data)) try { // 解析 JSON 数据 bufferErrorResponse = JSON.parse(decodedString) // 获取错误消息 errorMessage = bufferErrorResponse.message || error.message || '' } catch { errorMessage = error.message || '' } } else { bufferErrorResponse = error?.response?.data || {} errorMessage = bufferErrorResponse.message || error.message || '' } if (error?.response?.status === 401) { let isJump = JSON.parse(sessionStorage.getItem('isJUmp')) sessionStorage.clear() if (!['cas', 'oauth'].includes(window.ssoConfig.mode)) { router.push({path: '/login'}) } } else if (errorMessage) { if (bufferErrorResponse.logId) { Message.errorLog(errorMessage, bufferErrorResponse.logId) } else { Message.error(errorMessage) } } NProgress.done() // 结束 return Promise.reject(errorMessage) } ) Message.errorLog = function(obj, logId) { if (typeof obj == 'string' && logId) { let msg = obj let log = `【日志ID:${logId}】` Message({ type: 'error', message: msg + "

" + log + '

', dangerouslyUseHTMLString: true }) } else { Message.error(obj) } } export default { $http: axios, request(data) { let reqData = data.data || {} //支持表达式作为域名解析 data.url = this.parseUrl(data.url) //统一拼接域名接口 if ( data.url.indexOf('http') == -1 && data.url.indexOf('/v3/weather/weatherInfo') == -1 ) { data.url = context.front + data.url } else if (data.url.indexOf('/v3/weather/weatherInfo') !== -1) { let pureFront = context.front.slice(0, context.front.indexOf('/fvue')) data.url = pureFront + data.url } if ( window.agentLeaderId && window.agentLeaderId != '0' && data.url.indexOf('leaderId=') < 0 && window.location.href.indexOf('/task/') > 1 ) { let mark = '&' if (data.url.indexOf('?') < 0) { mark = '?' } data.url += mark + 'leaderId=' + window.agentLeaderId } let requestData = { url: data.url, data: reqData, method: data.method || 'GET', params: data.params || {}, onUploadProgress: data.onUploadProgress || null, headers: data.headers || '', responseType: data.responseType || 'json', isShowMessage: data.isShowMessage, CancelToken: data.CancelToken, timeout: data.timeout } return axios(requestData) }, download(url) { return this.request({ url, method: 'POST', responseType: 'arraybuffer' }) }, downloadGet(url) { return this.request({ url, method: 'GET', responseType: 'arraybuffer' }) }, downloadPostCopy(url, data) { return this.request({ url, method: 'post', data: data, responseType: 'arraybuffer' }) }, downloadGetCopy(url, data) { return this.request({ url, method: 'get', data: data, responseType: 'arraybuffer' }) }, get(url, type, isShowMessage) { return this.request({ url, responseType: type, isShowMessage: isShowMessage }) }, post(url, data, responseType, timeout) { return this.request({ url, data, method: 'POST', responseType: responseType, timeout }) }, put(url, data, responseType) { return this.request({ url, data, method: 'PUT', responseType: responseType }) }, remove(url) { return this.request({ url, method: 'DELETE' }) }, postAduit(url, data, headers) { return this.request({ url, data, method: 'POST', headers: headers }) }, getDown(url, type, isShowMessage) { console.log(url) console.log(type) return this.request({ url, responseType: type, isShowMessage: isShowMessage }) }, getContext() { return context }, parseUrl(url) { if (url === '') return let ctx = this.getContext(), reg = /^(\$\{(\w+)})\/.*$/ let match = reg.exec(url) if (match != null) { let name = match[2], mc = match[1], val = ctx[name] if (!val) { throw new Error( "The '" + name + "' in url:" + url + ' does not defined in context provider.' ) } return url.replace(mc, val) } else { return url } } }