本文介绍: 【代码】axios结合ts使用,取消请求,全局统一获取数据,抛出错误信息。
通常在开发时,后端向前端返回的数据可以如下:
- 1 使用restful api充分利用http状态码,然后在data中追加code字段,请求成功返回200,请求失败返回404,401,500等状态码,并且在code字段中给出详细的字符串信息
- 2 再包一层,所有请求不论失败还是成功状态返回均为200,然后在code中,返回实际的成功或失败的原因(可以是number,也可以是string)
以下以第二种为例:
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 };
原文地址:https://blog.csdn.net/weixin_56624286/article/details/135890585
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_63319.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。