赞
踩
通常在开发时,后端向前端返回的数据可以如下:
以下以第二种为例:
type Content = Array<unknown> | Record<string, unknown> | null; interface CustomResponse<T extends Content = Content> { code: number;//具体的code,这里依然使用的400,401等200表示成功 data: T; msg: string; } export enum Method { /** Get请求 */ Get = 'GET', /** Post请求 */ Post = 'POST', /** Put请求 */ Put = 'PUT', /** Delete请求 */ Delete = 'DELETE', }
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; import router from '@/router'; import { ElMessage, ElMessageBox } from 'element-plus'; import { localStorage } from '@/storage'; import { Method } from '@/enum'; import useStore from '@/store'; import qs from 'qs'; // 白名单列表,用于直接显示前端定义的错误 const whiteList: string[] = []; const requests: any[] = []; const cancelRequest = (config: any, cancelAll = false) => { for (const req in requests) { if (!cancelAll) { if (requests[req].url === `${config.method}-${config.url}`) { requests[req].controller.abort(); requests.splice(Number(req), 1); } } else { requests[req].controller.abort(); requests.splice(Number(req), 1); } } }; // 创建 axios 实例 const service = axios.create({ baseURL: import.meta.env.DEV ? 'api-dev' : 'api-prod', timeout: 60000, }); // 请求拦截器 service.interceptors.request.use( (config: AxiosRequestConfig) => { const { user } = useStore(); // 请求自动添加token if (user.token) { config.headers!.Authorization = `${localStorage.get('token')}`; } // 请求队列,用于取消请求 const controller = new AbortController(); config.signal = controller.signal; requests.push({ url: `${config.method}-${config.url}`, controller: controller, }); return config; }, error => { return Promise.reject(error); } ); // 响应拦截器 service.interceptors.response.use( (response: AxiosResponse) => { const { status } = response; if (status === 200) { switch (response.data.code) { case 200: return response.data; case 404: // 自定义的错误码,可以与http状态码一致,前后端约定即可 // 同时根据错误码进行跳转,清空缓存等动作 break; ... ... default: break; } } return response.data; }, error => { return Promise.reject(new Error(error.message || 'Error')); } ); function customRequest( method: Method ): <T extends Content>( url: string, data?: Record<string, any>, options?: AxiosRequestConfig ) => Promise<T> { return async function <T extends Content>( url: string, data?: Record<string, any>, options?: AxiosRequestConfig ) { let restParams = {}; if (method === Method.Get) { restParams = { params: { ...data?.params }, paramsSerializer: function (params: any) { //arg: [1, 2]会被转换为不同形式: indices转换为'arg[0]=1&arg[1]=2' brackets转换为'arg[]=1&arg[]=2' repeat转换为'arg=1&arg=2' return qs.stringify(params, { arrayFormat: 'repeat' }); }, }; } else { restParams = { data, ...options, }; } const res = await service.request<T, CustomResponse<T>>({ url, method: method, ...restParams }); // 为了不在每个请求后添加如下代码,所以在此统一处理 if (res.code === 200 && res.data) { return res.data; } throw res.msg; }; } // axios 实例 export default service; // 自定义axios 实例 export const requestService = { get: customRequest(Method.Get), post: customRequest(Method.Post), put: customRequest(Method.Put), delete: customRequest(Method.Delete), }; export { cancelRequest, requests };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。