当前位置: 首页 > news >正文

vue3+ts 简单封装axios:实现错误重试、重复请求取消、手动取消

注意:需要安装crypto-js库

  1. utils\request.ts中:

    import axios from "axios";
    import type { InternalAxiosRequestConfig, AxiosResponse, AxiosInstance } from "axios";
    import { useRequeryStore } from "@/store/request";
    const useRequeryStoreInfo = useRequeryStore();let isLogoutShowing = false; // 登录过期弹窗锁// 创建Axios实例
    const axiosInstance: AxiosInstance = axios.create({baseURL: import.meta.env.VITE_BASE_URL,timeout: 60000 // 延时时间:60s
    });// 请求拦截器
    axiosInstance.interceptors.request.use((config: InternalAxiosRequestConfig) => {// 添加tokenlet token = useRequeryStoreInfo.getToken;if (token) config.headers["Authorization"] = "Bearer " + token;const key = useRequeryStoreInfo.getRequestKey(config);// 移除旧的请求useRequeryStoreInfo.removeOldRequest(key);// 开始新的请求const controller = new AbortController();config.signal = controller.signal;useRequeryStoreInfo.setRequest(key, controller);return config;},(error) => {return Promise.reject(error);}
    );// 响应拦截器
    axiosInstance.interceptors.response.use((response: AxiosResponse) => {// 移除完成的请求useRequeryStoreInfo.removeNewRequest(response.config);// 错误处理if (response.data.code != 200) {responseError(response.data.code, response.data.message);return Promise.reject(response.data);}let config = response.config;console.log(`%c${config.baseURL}${config.url} %c${config.method?.toUpperCase()}`, "color:#409EFF; font-weight:bold;", "color:#67C23A; font-weight:bold;");console.log("- 请求参数", config.data, config.params);console.log("- 响应结果", response.data);return Promise.resolve(response.data);},async (error) => {let config = error.config;// 移除完成的请求、不包括主动取消if (error.code !== "ERR_CANCELED" && config) useRequeryStoreInfo.removeNewRequest(error.config);// 错误重试if (config.errorRetry) {const retryTotal: number = config.retryTotal ?? 3;const retryCount: number = config.retryCount ?? 0;if (retryCount < retryTotal) {ElMessage.warning(`请求失败,正在进行第${retryCount + 1}次尝试重新请求...`);config.retryCount = retryCount + 1;await new Promise((resolve) => setTimeout(resolve, 1000));const newController = new AbortController();config.signal = newController.signal;return axiosInstance(config);}}// 错误提示处理if (error.code !== "ERR_CANCELED") {let { message } = error;if (message == "Network Error") message = "连接异常,请稍后重试...";else if (message.includes("timeout")) message = "请求超时,请稍后重试...";ElMessage.error(message || "未知错误,请联系管理员!");}return Promise.reject(error);}
    );// 响应错误处理
    const responseError = (code: number, message: string) => {switch (code) {case 401:if (isLogoutShowing) return;isLogoutShowing = true;ElMessageBox.confirm("登录过期,是否重新登录?", "Warning", {confirmButtonText: "重新登录",cancelButtonText: "取消",type: "warning"}).then(() => {useRequeryStoreInfo.logout();}).finally(() => {isLogoutShowing = false;});break;default:ElMessage.error(message || "未知错误,请联系管理员!");break;}
    };
    export default axiosInstance;
    
  2. store\request.ts中:

    import { defineStore } from "pinia";
    import { MD5 } from "crypto-js";
    import router from "@/router";/*** 网络请求* requestList:网络请求*/
    interface Config {method?: string;url?: string;data?: any;params?: any;
    }
    interface State {token: string;requestList: Map<string, AbortController>;
    }
    export const useRequeryStore = defineStore("requery", {persist: {pick: ["token"]},state: (): State => ({token: "",requestList: new Map()}),getters: {// 获取requestListgetRequestList: (state) => state.requestList,// 获取TokengetToken: (state) => state.token},actions: {// 重新登录logout() {router.push({ name: "login" });localStorage.clear();sessionStorage.clear();},// 设置TokensetToken(token: string) {this.token = token;},/*** 获取请求key* @param {Config} config 需要method, data, url, params数据* @returns {string} key*/getRequestKey(config: Config): string {const { method, url, data, params } = config;let newData = typeof data === "object" ? JSON.stringify(data) : data;let newParams = typeof params === "object" ? JSON.stringify(params) : params;return MD5([method, url, newParams, newData].join("&")).toString();},/*** 取消请求* @param {string} key 通过getRequestKey生成的key* @param {boolean} isMessage 是否需要提示* @param {boolean} message 提示内容*/cancelRequest(key: string, isMessage: boolean = false, message: string = "请勿重复操作!") {if (this.getRequestList.has(key)) {const controller = this.requestList.get(key);if (controller) {controller.abort();this.requestList.delete(key);}if (isMessage) ElMessage.warning(message);}},// 存储请求数据setRequest(key: string, controller: AbortController) {this.requestList.set(key, controller);},// 移除旧的请求removeOldRequest(key: string) {this.cancelRequest(key, true);},// 移除完成的请求removeNewRequest(config: Config) {const key = this.getRequestKey(config);this.getRequestList.delete(key);},/*** 手动取消请求* @param {Config} config 需要method, data, url, params数据,请和请求的时候一模一样*/manualCancelRequest(config: Config) {const key = this.getRequestKey(config);this.cancelRequest(key, true, "成功取消请求!");}}
    });
    
  3. 封装请求接口:在api\login.ts

    import request from "@/utils/request";// 登录
    export const getLogin = (data?: any) => {return request({url: "/user/login",method: "post",data});
    };
    
  4. 错误重复请求:在api\login.ts

    import request from "@/utils/request";// 登录
    export const getLogin = (data?: any) => {return request({url: "/user/login",method: "post",data,errorRetry:true,retryTotal:3,});
    };
    
http://www.jsqmd.com/news/34335/

相关文章:

  • 2025 年压敏胶源头厂家最新推荐榜单:覆盖多类型产品且经协会测评的权威甄选指南耐高温压敏胶/环保压敏胶/水性压敏胶/医用压敏胶公司推荐
  • window.open()与session
  • 2025年安全网与遮阳网厂家综合实力Top5
  • 2025年热门的安全检测检验公司榜单
  • 2025年安全检测检验公司排行榜:前十名权威推荐与行业洞察
  • 2025年有实力的安全检测检验公司热门排行前十强榜单
  • 2025年11月四川护栏厂家排名榜:五家实力对比与选购指南
  • 2025年11月四川护栏厂家推荐榜:五强产能对比与口碑评价全解析
  • 同城洗车小程序系统:一站式洗车服务解决方案
  • 2025 年物业管理公司服务口碑排行榜权威发布:五标认证企业与精细化服务实力最新推荐政府机构/写字楼/商场/园区物业管理公司服务推荐
  • Tauri跨平台开发:Rust后端+React前端桌面应用实践 - 教程
  • 魔方报名缴费系统:高效便捷的全流程报名解决方案
  • 2025 物业托管公司最新推荐榜:权威测评出炉,,多业态服务实力甄选园区/银行/剧院/商业物业托管公司服务推荐
  • 打破孤立的隐形枷锁:AI智能守护如何拯救校园中的“边缘”学生
  • 文字识别
  • 知识付费网盘变现微信小程序系统:资源变现与流量裂变解决方案
  • 热血传奇,经典重现,完美传奇游戏详细图文架设教程
  • STM32和ESP32有什么区别?如何选开发板?资深工程师学习路线建议!
  • 问题Whitelabel Error Page用Maven方式构建Spring Boot Web
  • TCP/IP 协议族—理论与实践(二) - 指南
  • 2025 年热熔胶源头厂家最新推荐排行榜:聚焦五大优质品牌,助力企业选对稳定供应商阻燃热熔胶/无初粘热熔胶/汽车热熔胶公司推荐
  • 维修厂家口碑排行榜单2025年:权威解析
  • 【分析报告】金风科技如何培养新一代风电人才
  • 2025 年倾斜开关厂家最新推荐榜:盘点市场认可度高的源头厂家,涵盖多类型倾斜开关优质品牌广州倾斜开关/贴片倾斜开关/电子式倾斜开关公司推荐
  • 金风科技如何培养新一代风电人才?深度解析金风科技的人才发展战略与实践
  • 2025年背封湿巾包装机生产厂家权威推荐榜单:棉片湿巾包装机/航空湿巾包装机/一次性湿巾包装源头厂家精选
  • C# 读取txt日志文件乱码
  • lua-zlib模块安装与使用
  • 智能驱动,安全可控:国标GB28181算法算力平台EasyGBS如何构建企业生产智能监控新模式
  • 2025年11月仿真花源头厂家推荐榜:五强工厂口碑与参数全解析