Spaces:
Runtime error
Runtime error
/** | |
* axios 网络请求工具 | |
*/ | |
import axios from 'axios'; | |
import api from './apiNames' | |
import url from './url' | |
// 服务器状态码 | |
const codeMessage:any = { | |
200: '服务器成功返回请求的数据。', | |
201: '新建或修改数据成功。', | |
202: '一个请求已经进入后台排队(异步任务)。', | |
204: '删除数据成功。', | |
400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。', | |
401: '用户没有权限(令牌、用户名、密码错误)。', | |
403: '用户得到授权,但是访问是被禁止的。', | |
404: '发出的请求针对的是不存在的记录,服务器没有进行操作。', | |
406: '请求的格式不可得。', | |
410: '请求的资源被永久删除,且不会再得到的。', | |
422: '当创建一个对象时,发生一个验证错误。', | |
500: '服务器发生错误,请检查服务器。', | |
502: '网关错误。', | |
503: '服务不可用,服务器暂时过载或维护。', | |
504: '网关超时。', | |
}; | |
// 接口返回状态码 | |
const apiCode: any = { | |
toast: 101, // 错误信息,需要toast提示 | |
loginFail: 10086, // 登录失效 | |
} | |
let request = axios.create({ | |
baseURL: url, | |
timeout: 2e4, | |
responseType: 'json', | |
}); | |
/** | |
* 异常处理程序 | |
*/ | |
const errorHandler = (response: any) => { | |
if (response && response?.status) { | |
const errorText = codeMessage[response.status] || response.statusText; | |
const { status, url } = response; | |
if (response?.status === 401) { // 登录失效 | |
setTimeout(() => { | |
window.sessionStorage.clear(); | |
window.location.href = `${window.location.origin}/login`; | |
}, 1e3); | |
} else { | |
console.log(`请求错误 ${status}: ${url},${errorText}`); | |
} | |
} | |
return response; | |
}; | |
// 取消请求 | |
const cancelAxios:any = []; | |
request.interceptors.request.use((config:any) => { | |
const c = config; | |
c.cancelToken = new axios.CancelToken((cancel:any) => { | |
cancelAxios.push(cancel); | |
}); | |
return c; | |
}, () => { | |
// console.log(error); | |
}); | |
// 触发axios取消事件,挂载到window | |
window.$cancelRequest = () => { | |
cancelAxios.forEach((element:any, index:number) => { | |
element('cancel'); | |
delete cancelAxios[index]; | |
}); | |
}; | |
// 过滤导出excel错误提示,文件流下载接口声明列表 | |
const list = [ | |
{ url: api.exportDetails, type: 'export', export: 1}, | |
]; | |
// 添加请求拦截器 | |
request.interceptors.request.use((config:any) => { | |
const finds = list.find(item => config.url.includes(item.url)); | |
const num = config[config.method.toUpperCase() === 'GET' ? 'params' : 'data']?.export || 0; | |
if (finds && num === 1) { // 下载 | |
config.responseType = 'blob' | |
} | |
return config | |
}, (error: any) => { | |
console.log(error) | |
}) | |
// 添加响应拦截器 | |
request.interceptors.response.use(async (response: any) => { | |
const options = response.config | |
const finds = list.find(item => options.url.includes(item.url)); | |
const num = options[options.method.toUpperCase() === 'GET' ? 'params' : 'data']?.export || 0; | |
if (finds && num === 1 && response.status === 200) { // 文件流下载,请求中必须含:export:1,可选fileName,默认时间 | |
const blob = new Blob([response.data], {type: 'application/vnd.ms-excel'}); | |
let filename = options[options.method.toUpperCase() === 'GET' ? 'params' : 'data']?.fileName || new Date().Format('YYYY-MM-DD hh:mm:ss'); | |
// 创建一个超链接,将文件流赋进去,然后实现这个超链接的单击事件 | |
const elink = document.createElement('a'); | |
elink.download = filename; | |
elink.style.display = 'none'; | |
elink.href = URL.createObjectURL(blob); | |
document.body.appendChild(elink); | |
elink.click(); | |
URL.revokeObjectURL(elink.href); // 释放URL 对象 | |
document.body.removeChild(elink); | |
return blob | |
} | |
if (response.status === 200) { // 一般性接口请求 | |
try { | |
if (response.data.code) { | |
if (response.data.code !== 200) { | |
if (response.data.code === apiCode.loginFail) { // 登录失效 | |
setTimeout(() => { | |
window.sessionStorage.clear(); | |
window.location.href = `${window.location.origin}/login`; | |
}, 1e3); | |
} | |
if (response.data.code === apiCode.toast) { | |
alert(response.data.errorMsg); | |
} else { | |
console.log(response.data.errorMsg); | |
} | |
} | |
} | |
} catch (err) { | |
console.log('接口请求失败'); | |
} | |
} else { | |
errorHandler(response) | |
} | |
return response.data; | |
}); | |
axios.defaults.withCredentials = true; | |
export default request |