| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- import Vue from 'vue'
- import axios from 'axios'
- import { MessageBox } from 'element-ui'
- import {
- baseURL,
- contentType,
- debounce,
- invalidCode,
- noPermissionCode,
- requestTimeout,
- successCode,
- recordRoute,
- loginInterception,
- } from '@/config'
- import router from '@/router'
- import store from '@/store'
- import qs from 'qs'
- import { isArray } from '@/utils/validate'
- let loadingInstance
- /**
- * 处理code异常
- * @param {*} code
- * @param {*} msg
- */
- const handleCode = (code, msg) => {
- switch (code) {
- case invalidCode:
- MessageBox.alert(
- `<div style="max-height:60vh;overflow:auto">${
- msg || `后端接口${code}异常`
- }</div>`,
- '错误',
- {
- type: 'error',
- dangerouslyUseHTMLString: true,
- showClose: true,
- }
- )
- store.dispatch('user/resetAccessToken')
- if (loginInterception) {
- try {
- const fullPath = router.currentRoute.fullPath
- if (recordRoute && fullPath) {
- router.push(`/login?redirect=${fullPath}`)
- } else {
- router.push('/login')
- }
- } catch (e) {
- // 兜底:直接跳转登录页
- window.location.href = '/login'
- }
- }
- break
- case noPermissionCode:
- store
- .dispatch('user/logout')
- .then(() => {
- if (recordRoute) {
- const fullPath = router.currentRoute.fullPath
- router.push(`/login?redirect=${fullPath}`)
- } else {
- router.push('/login')
- }
- })
- .catch(() => {
- // logout时可能因为token过期报401错误,此时用href跳转到login页面
- window.location.href = '/login'
- })
- break
- default:
- if (Number(code) === 500) {
- // 500 保持原来的轻提示样式
- Vue.prototype.$baseMessage(msg || `后端接口${code}异常`, 'error')
- } else if (Number(code) === 250) {
- // 250 使用现在的可滚动模态框
- MessageBox.alert(
- `<div style="max-height:60vh;overflow:auto">${
- msg || `后端接口${code}异常`
- }</div>`,
- '错误',
- {
- type: 'error',
- dangerouslyUseHTMLString: true,
- showClose: true,
- }
- )
- } else {
- // 其他按当前默认(模态框)处理
- MessageBox.alert(`${msg || `后端接口${code}异常`}`, '错误', {
- type: 'error',
- dangerouslyUseHTMLString: true,
- showClose: true,
- })
- }
- break
- }
- }
- const instance = axios.create({
- baseURL,
- timeout: requestTimeout,
- // headers: {
- // 'Content-Type': contentType,
- // },
- headers: {
- 'Content-Type': contentType,
- 'ngrok-skip-browser-warning': 'true',
- },
- })
- instance.interceptors.request.use(
- (config) => {
- if (config.headers && config.headers.constructor == String) {
- try {
- config.headers = JSON.parse(config.headers)
- } catch (e) {
- MessageBox.alert(
- `请求头部不是有效的JSON格式:${config.headers}`,
- '请求错误',
- { type: 'error', dangerouslyUseHTMLString: true }
- )
- throw e
- }
- }
- if (!config.headers || !config.headers.Authorization) {
- const accessToken = store.getters['user/accessToken']
- if (accessToken) {
- config.headers['Authorization'] = `Bearer ${accessToken}`
- }
- }
- if (
- config.data &&
- config.headers['Content-Type'] ===
- 'application/x-www-form-urlencoded;charset=UTF-8'
- )
- config.data = qs.stringify(config.data)
- config.headers['Accept-Language'] = localStorage.getItem('lang') || 'zh-CN'
- if (debounce.some((item) => config.url && config.url.includes(item)))
- loadingInstance = Vue.prototype.$baseLoading()
- return config
- },
- (error) => {
- return Promise.reject(error)
- }
- )
- instance.interceptors.response.use(
- (response) => {
- if (loadingInstance) loadingInstance.close()
- const { data, config, headers } = response
- const { code, msg, message } = data
- if (config) {
- const { responseType } = config
- // 请求的返回值类型为arraybuffer时返回headers
- if (responseType && responseType == 'arraybuffer') {
- return { data, headers }
- }
- }
- if (headers) {
- // 附件下载,需要返回 headers
- const content = headers['content-disposition']
- if (content && content.startsWith('attachment;')) {
- return { data, headers }
- }
- }
- // TODO:暂时允许请求不返回code
- if (code === undefined) {
- return data
- }
- // 操作正常Code数组
- const codeVerificationArray = isArray(successCode)
- ? [...successCode]
- : [...[successCode]]
- // 是否操作正常
- if (codeVerificationArray.includes(code)) {
- return data
- } else {
- handleCode(code, message)
- return Promise.reject(
- '请求异常拦截:' + JSON.stringify({ url: config.url, code, message }) ||
- 'Error'
- )
- }
- },
- (error) => {
- if (loadingInstance) loadingInstance.close()
- const { response, message } = error
- if (error.response && error.response.data) {
- const { status, data } = response
- //data.msg
- handleCode(status, data.message || message)
- return Promise.reject(error)
- } else {
- let { message } = error
- if (message === 'Network Error') {
- message = '后端接口连接异常'
- }
- if (message.includes('timeout')) {
- message = '后端接口请求超时'
- }
- if (message.includes('Request failed with status code')) {
- const code = message.substr(message.length - 3)
- message = '后端接口' + code + '异常'
- }
- MessageBox.alert(message || `后端接口未知异常`, '错误', {
- type: 'error',
- dangerouslyUseHTMLString: true,
- showClose: true,
- })
- return Promise.reject(error)
- }
- }
- )
- export default instance
|