标签:pendingMap return url request js error 封装 config const
import Vue from 'vue' import router from '@/router' import store from '@/store' import axios from 'axios' import { Message } from 'element-ui'const popupErrorMessage = (function popupErrorMessage() { const cacheMessage = [] return function(message) { if (!message) { return } if (cacheMessage.indexOf(message) !== -1) { return } Message.error(message) cacheMessage.push(message) const timeoutId = setTimeout(() => { cacheMessage.splice(cacheMessage.indexOf(message), 1) clearTimeout(timeoutId) }, 1000) } })()
Vue.prototype.$http = axios
const CancelToken = axios.CancelToken class PendingRequest { constructor() { /** @type { Map<string, import('axios').Canceler> } */ this.pendingMap = new Map() }
/** * 发起新的请求前,清除重复请求,并生成新的请求token * @param {string} url - 请求的url做为唯一key * @returns {import('axios').CancelToken}} */ cancelToken(url) { const { pendingMap } = this const key = url.split('?')[0] if (pendingMap.has(key)) { pendingMap.get(key)('取消重复请求') } return new CancelToken(cancel => { pendingMap.set(key, cancel) }) }
cancelAllToken() { const { pendingMap } = this pendingMap.forEach(cancelToken => cancelToken('取消重复请求')) pendingMap.clear() }
/** * 删除已完成的请求token * @param {string} url - 请求的url做为唯一key */ delete(url) { const key = url.split('?')[0] this.pendingMap.delete(key) } }
const pendingRequest = new PendingRequest()
const request = axios.create({ baseURL: process.env.VUE_APP_URL, })
request.interceptors.request.use( config => { if (!config.noCancelPendingRequest) { config.cancelToken = pendingRequest.cancelToken(config.url) }
const token = localStorage.getItem('token') if (token) { config.headers.token = token // 请求头部添加token }
return config }, error => { return Promise.reject(error) }, )
request.interceptors.response.use( response => { const { config, data } = response pendingRequest.delete(config.url)
if (data.respCode === '0000' || data.respCode === '200') { return Promise.resolve(data) } const errorMessage = getCustomErrorMessage(data.respCode || data.status) if (errorMessage === false) { console.error(`接口响应错误: ${config.url}\n响应内容: ${data}`) } if (!process.env.production) { console.warn( `error_code: ${data.respCode},error_message: ${data.respMsg}`, ) }
!config.noHandleErrorMessage && popupErrorMessage(errorMessage || data.respMsg || data)
return Promise.reject(data) }, error => { const { response, config = {} } = error if (response) { const errorMessage = getHttpErrorMessage(response.status) errorMessage && popupErrorMessage(errorMessage) return Promise.reject({ message: errorMessage, respCode: response.status, }) } else { if (config.noHandleErrorMessage) { // 不处理错误消息 return Promise.reject(error) } else if (error.message.includes('timeout')) { // 请求超时或者网络有问题 popupErrorMessage('请求超时!请检查网络是否正常') } else if (error.message.includes('Network Error')) { popupErrorMessage('网络连接错误') } else if (error.message === '取消重复请求') { // 取消重复请求 不做处理 return Promise.reject({}) } else { popupErrorMessage('请求失败,请检查网络是否已连接') } } return Promise.reject(error) }, )
function getHttpErrorMessage(code) { switch (code) { case 404: return '网络请求不存在' case 503: return '服务器目维护中' case 500: return '服务器内部错误' } }
function getCustomErrorMessage(code) { if (!code) { return false } switch (code.toString()) { case '403': handleCustom403Error() return '登录已失效,请重新登录' case '1003': return '没有记录被修改' case '1006': return '没有记录被删除' } }
function handleCustom403Error() { pendingRequest.cancelAllToken() store.commit('CLEAR_VIEW_TAG') if (localStorage.getItem('token')) { localStorage.clear() router.push('/login') } }
export function cancelToken(url) { const { pendingMap } = pendingRequest const key = url.split('?')[0] if (pendingMap.has(key)) { pendingMap.get(key)('取消重复请求') } }
export default function(url, params = {}, config = {}) { return request.post(url, params, config).catch(error => { !process.env.production && console.log(error) return Promise.reject(error) }) }
标签:pendingMap,return,url,request,js,error,封装,config,const 来源: https://www.cnblogs.com/xiaoxiao95/p/16385417.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。