/** * author: 徐青松 * day: 2022-11-10 * @returns 返回一个createRequest方法,执行这个方法后会返回一个封装好的axios实体。 */ import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios' import { Action, ElMessageBox } from 'element-plus' import NProgress from 'nprogress' import CancelToken from './cancalToken' import { __getItem } from './storage' import { i18n } from '../i18n' interface BaseResponse { status: number data?: T message?: string ok?: boolean } interface Request { get: (url: string, params?: unknown) => Promise>>; put: (url: string, params?: unknown) => Promise>>; post: (url: string, params?: unknown, config?: Object) => Promise>>; delete: (url: string, params?: unknown) => Promise>>; upload: (url: string, params?: unknown, config?: Object) => Promise>>; download: (url: string) => void } let isOpenMessage = false /** * * @param requestBaseURL * @param timeout * @returns */ function createRequest (requestBaseURL?: string, timeout?: number): Request { const serveConfig = window.sessionStorage.getItem('serveConfig') || '{}' let baseUrl = JSON.parse(serveConfig)?.baseURL || '/api' // 创建axios实例 const service: AxiosInstance = axios.create({ baseURL: requestBaseURL || baseUrl, // timeout: timeout || 10000, // 不设置的时候是0,永不超时 withCredentials: true }) service.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8' // 请求拦截,配置token及cancalToken添加及移除 service.interceptors.request.use( (config): AxiosRequestConfig => { const serveConfig: string = window.sessionStorage.getItem('serveConfig') || '{}' const tokenName = JSON.parse(serveConfig)?.token const tokenValue = __getItem('x-auth-token') if (tokenValue) { // @ts-ignore config.headers[tokenName] = tokenValue } const language = __getItem('language', 'localStorage') // @ts-ignore config.headers['accept-language'] = language === 'en' ? 'en-US' : 'zh-CN' // @ts-ignore config.headers['AUTH-ROUTE'] = window?.location?.pathname || '/resourceDirectory/index' // 请求开始前,检查一下是否已经有该请求了,有则取消掉该请求 CancelToken.removePending(config) // 把当前请求添加进去 CancelToken.addPending(config) return config }, (error) => { // 请求被取消 if (error.name === 'CanceledError') return null return error } ) // let failRequestList: RequestInfo[] = []; // let retryMap = new WeakMap(); // function retryAllFailRequest() { // failRequestList.forEach(info => { // //每个请求最多重试3次 // let retryTimes = retryMap.get(info.config); // if (!retryTimes) { // retryTimes = 1; // retryMap.set(info.config, retryTimes); // } else if (retryTimes >= 3) { // retryMap.delete(info.config); // return; // } else { // retryMap.set(info.config, retryTimes + 1); // } // service(info.config) // .then(info.resolve) // .catch(info.reject); // }); // failRequestList = []; // } // 响应拦截器 service.interceptors.response.use( response => { // 是否判断 // if (response.data.code !== 1) { // return Promise.reject(response) // } else { // return response // } // 接口响应之后把这次请求清除 CancelToken.removePending(response.config) if (response.data.code === 111) { sessionStorage.setItem('token', '') // token过期操作 } return response }, err => { if (err.name === 'CanceledError') return if (err.response?.status === 401) { if (isOpenMessage) return isOpenMessage = true const serveConfig: string = window.sessionStorage.getItem('serveConfig') || '' const serveConfigObj = JSON.parse(serveConfig) const errMsg = err.response?.data?.message // || err.message ElMessageBox.alert( errMsg || serveConfigObj?.logoutPrompt || i18n.global.t('userLoginInvalid'), i18n.global.t('confirmTips'), { confirmButtonText: i18n.global.t('confirm'), callback: (action: Action) => { // 跳转到登陆 isOpenMessage = false window.location.href = serveConfigObj?.defaultLoginHref || serveConfigObj?.defaultHref }, beforeClose: (action, instance, done) => { done() } } ) return } return Promise.resolve(err) } ) /** * 请求函数 * @param config * @returns */ const doRequest = (config: AxiosRequestConfig): Promise>> => { return new Promise((resolve, reject) => { NProgress.start() service.request>(config).then( res => { resolve(res) NProgress.done() }, err => { reject(err) NProgress.done() } ) }) } /** * 抛出的请求集合,需要扩展请求类型可以再次扩展 */ const request: Request = { get (url, params?) { return doRequest({ url: url, method: 'get', params: params }) }, post (url, params?, config?) { return doRequest({ url: url, method: 'post', data: typeof (params) === 'string' ? params : JSON.stringify(params), ...config }) }, put (url, params?) { return doRequest({ url: url, method: 'put', data: params }) }, delete (url, params?) { return doRequest({ url: url, method: 'delete', data: params }) }, upload (url, file?, config?) { return doRequest({ url: url, method: 'post', data: file, headers: { 'Content-Type': 'multipart/form-data' }, ...config }) }, download (url) { const iframe = document.createElement('iframe') iframe.style.display = 'none' iframe.src = url iframe.onload = function () { document.body.removeChild(iframe) } document.body.appendChild(iframe) } } return request } export { createRequest }