/** * 网络请求配置 */ import { PendingType, ResponseData } from '@/types/request' import CONSTS from '@/utils/consts' import history from '@/utils/history' import { storage } from '@/utils/util' import { message } from 'antd' import axios, { AxiosRequestConfig, AxiosResponse } from 'axios' const pending: Array = [] const removePending = (config: AxiosRequestConfig) => { for (const key in pending) { const item: number = +key const list: PendingType = pending[key] // 当前请求在数组中存在时执行函数体 if (list.url === config.url && list.method === config.method && JSON.stringify(list.params) === JSON.stringify(config.params) && JSON.stringify(list.data) === JSON.stringify(config.data)) { // 执行取消操作 list.cancel('操作太频繁,请稍后再试') // 从数组中移除记录 pending.splice(item, 1) } } } const service = axios.create({ baseURL: process.env.NODE_ENV === 'development' ? CONSTS.BASE_URL.DEV : CONSTS.BASE_URL.PROD, timeout: 5000, withCredentials: true }) /** * request 拦截器 */ service.interceptors.request.use( request => { removePending(request) request.cancelToken = new axios.CancelToken(func => { pending.push({ url: request.url, method: request.method, params: request.params, data: request.data, cancel: func }) }) if (request?.method !== 'get') { request.headers['X-CSRF-Token'] = storage.get('csrf_token') } return request }, err => { console.log(err) return Promise.reject(err) } ) /** * response 拦截器 */ service.interceptors.response.use( (response: AxiosResponse) => { removePending(response.config) const data: ResponseData = response.data // 对Code不等于Success进行message提示 if (data.code !== CONSTS.RET_CODE.SUCCESS) { message.error(data.msg) switch (data.code) { case 1: history.push('/login') break default: break } } if (response.config.method?.toLocaleUpperCase() === 'GET') { const token = response?.headers['x-csrf-token'] storage.set('csrf_token', token) } return response }, error => { const response = error.response const config = error.config const { COUNT: RETRY_COUNT, DELAY: RETRY_DELAY } = CONSTS.RETRY if (config && RETRY_COUNT) { // 设置一个静态属性追踪重试次数 config.__retryCount = config.__retryCount || 0 // 重试次数已用完 if (config.__retryCount >= RETRY_COUNT) { return Promise.reject(response) } config.__retryCount++ // 利用promise处理请求间隔 const backoff = new Promise(resolve => { setTimeout(() => { resolve() }, RETRY_DELAY | 1) }) // 重新发起请求 return backoff.then(() => service(config)) } return Promise.reject(response) } ) export default { get(url: string, params?: any) { return service.get(url, { params }) }, post(url: string, data?: any) { return service.post(url, data ) }, del(url: string, data?: any) { return service.delete(url, data) } }