Axios 二次封装高级教程(含请求取消等功能)

Axios 二次封装高级教程(含请求取消等功能)

整理不易,收藏、点赞、关注哦!


一、总体架构设计

  • 目的:构建一套功能完善、易用且健壮的 HTTP 请求封装层

  • 核心功能

    • 请求拦截、响应拦截
    • 请求取消(防止重复请求、接口防抖)
    • 请求合并与批量处理
    • 缓存策略(内存缓存、localStorage、sessionStorage)
    • 失败重试机制
    • 上传下载进度监听
    • 状态化 hooks 集成(loading、error、data 管理)
    • 统一接口调用管理

二、Axios 实例创建与基础配置

import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, Canceler } from 'axios'const pendingRequestMap = new Map<string, Canceler>()// 生成请求唯一key,便于取消重复请求
function getRequestKey(config: AxiosRequestConfig): string {const { method, url, params, data } = configreturn [method, url, JSON.stringify(params), JSON.stringify(data)].join('&')
}// 添加请求到pending队列
function addPendingRequest(config: AxiosRequestConfig) {const requestKey = getRequestKey(config)if (pendingRequestMap.has(requestKey)) {// 取消重复请求pendingRequestMap.get(requestKey)?.('取消重复请求')}config.cancelToken = new axios.CancelToken((cancel) => {pendingRequestMap.set(requestKey, cancel)})
}// 移除请求
function removePendingRequest(config: AxiosRequestConfig) {const requestKey = getRequestKey(config)if (pendingRequestMap.has(requestKey)) {pendingRequestMap.delete(requestKey)}
}const service: AxiosInstance = axios.create({baseURL: import.meta.env.VITE_API_BASE_URL,timeout: 15000,headers: {'Content-Type': 'application/json;charset=UTF-8',},
})// 请求拦截器
service.interceptors.request.use((config) => {removePendingRequest(config) // 移除之前的请求addPendingRequest(config) // 添加当前请求// 这里可以加token等鉴权信息// const token = localStorage.getItem('token')// if (token) config.headers.Authorization = `Bearer ${token}`return config},(error) => Promise.reject(error)
)// 响应拦截器
service.interceptors.response.use((response: AxiosResponse) => {removePendingRequest(response.config)// 统一处理状态码const { data } = responseif (data.code !== 0) {// 自定义错误处理return Promise.reject(new Error(data.message || 'Error'))}return data},(error) => {if (axios.isCancel(error)) {console.warn('请求被取消:', error.message)return Promise.reject({ canceled: true })}return Promise.reject(error)}
)export default service

三、请求取消与防抖(防重复请求)

  • 场景:用户快速重复点击按钮,多次发送相同请求
  • 解决:通过cancelToken取消前一个重复请求,保证接口调用稳定

核心逻辑已在上面pendingRequestMap实现,结合唯一请求Key判断。


四、多请求合并(批量接口请求)

/*** 批量请求示例* @param urls 请求地址数组*/
function batchRequest(urls: string[]) {const requests = urls.map((url) => service.get(url))return axios.all(requests).then(axios.spread((...responses) => responses))
}// 使用
batchRequest(['/api/a', '/api/b', '/api/c']).then(([resA, resB, resC]) => {console.log(resA, resB, resC)
})

五、缓存策略(内存缓存 + 本地缓存)

const cacheMap = new Map<string, any>()// 简单缓存示例
function requestWithCache<T = any>(config: AxiosRequestConfig, useCache = true): Promise<T> {const key = getRequestKey(config)if (useCache && cacheMap.has(key)) {return Promise.resolve(cacheMap.get(key))}return service.request<T>(config).then((res) => {cacheMap.set(key, res)return res})
}
  • 可根据业务需求,扩展使用localStoragesessionStorage缓存,并设置过期时间。

六、自动失败重试机制

interface RetryConfig extends AxiosRequestConfig {retry?: number // 重试次数retryDelay?: number // 重试间隔ms
}function retryRequest(config: RetryConfig): Promise<any> {const { retry = 3, retryDelay = 1000 } = configlet currentRetry = 0const request = (): Promise<any> => {return service.request(config).catch((error) => {if (currentRetry < retry) {currentRetry++return new Promise((resolve) => setTimeout(resolve, retryDelay)).then(request)}return Promise.reject(error)})}return request()
}
  • 可以在请求层或调用层根据需求灵活调用。

七、上传和下载进度监听

// 上传进度
function uploadFile(url: string, file: File, onProgress: (percent: number) => void) {const formData = new FormData()formData.append('file', file)return service.post(url, formData, {headers: { 'Content-Type': 'multipart/form-data' },onUploadProgress: (progressEvent) => {const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total)onProgress(percent)},})
}// 下载进度
function downloadFile(url: string, onProgress: (percent: number) => void) {return service.get(url, {responseType: 'blob',onDownloadProgress: (progressEvent) => {const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total)onProgress(percent)},})
}

八、封装状态式 Hook(结合 Vue 3 Composition API)

import { ref } from 'vue'interface UseRequestOptions {manual?: boolean // 是否手动调用retry?: numberretryDelay?: number
}export function useRequest<T = any>(requestFn: (...args: any[]) => Promise<T>,options: UseRequestOptions = {}
) {const data = ref<T | null>(null)const loading = ref(false)const error = ref<Error | null>(null)const fetch = async (...args: any[]) => {loading.value = trueerror.value = nulltry {data.value = await requestFn(...args)loading.value = falsereturn data.value} catch (err: any) {error.value = errloading.value = falsethrow err}}if (!options.manual) {fetch()}return { data, loading, error, fetch }
}
  • 使用示例:
import { useRequest } from './useRequest'
import service from './axios'const { data, loading, error, fetch } = useRequest(() => service.get('/api/user'))

九、文件上传并发送给后端(结合FileReader)

function uploadFileWithPreview(file: File, url: string) {return new Promise((resolve, reject) => {const reader = new FileReader()reader.readAsDataURL(file) // 读取文件为base64编码reader.onload = () => {// 可以先预览file的base64,也可以直接上传二进制const formData = new FormData()formData.append('file', file) // 直接上传文件service.post(url, formData, {headers: { 'Content-Type': 'multipart/form-data' },}).then(resolve).catch(reject)}reader.onerror = (err) => reject(err)})
}

十、总结

  1. 请求取消通过唯一请求key + CancelToken实现,防止重复请求。
  2. 多请求合并使用axios.allaxios.spread实现批量请求并行。
  3. 缓存策略基于请求key设计内存或本地缓存,提升请求效率。
  4. 自动重试可根据失败情况自动重试,增强请求鲁棒性。
  5. 上传/下载进度监听灵活支持文件上传和下载的进度反馈。
  6. 状态式 Hook结合 Vue 3 Composition API,实现简洁易用的请求状态管理。
  7. 文件上传可结合 FileReader 实现预览和上传双功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/89709.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/89709.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MobileNet V1的Pytorch实现并加载预训练模型进行验证

一. 环境 windonws 11RTX5060CUDA 12.8Pytorch 2.9.0dev20250630cu128torchvision 0.23.0dev20250701cu128 二. 代码 基于Mobilenet-CustomData 的Mobilenet_Pretrain.ipynb 1. 定义Mobile Net V1 import os import time import torch import torch.nn as nn import torch…

HTTP协议利用TCP的特性来实现长连接

在讨论网络协议时,经常会有人提出这样一个问题:“既然HTTP是基于TCP的,而TCP本身支持长连接,为什么HTTP不支持长连接?”这种说法其实是一种误解。实际上,HTTP确实可以并且经常使用长连接(也称为持久连接)。 什么是长连接? 首先,我们需要明确什么是“长连接”。在网…

整流电路Multisim电路仿真实验汇总——硬件工程师笔记

目录 1 整流电路基础 1.1 整流电路基本原理 1.2 整流电路的类型 1.2.1 单相整流电路 1.2.2 三相整流电路 1.3 整流电路的应用 1.3.1 直流电源 1.3.2 电池充电器 1.3.3 变频调速系统 1.34 电解和电镀 1.4 整流电路的优缺点 1.4.1 优点 1.4.2 缺点 2 二极管整流电路…

LangChain 全面入门

什么是 LangChain&#xff1f; LangChain 是一个专门为 大语言模型 (LLM) 应用开发设计的开源框架&#xff0c;帮你快速实现&#xff1a; • 多轮对话 • 知识库问答 (RAG) • 多工具协同调用 (function calling / tool) • 智能体 Agent 自动决策任务链 解耦 LLM 接口、Prom…

RabbitMQ 高级特性之消息确认

1. 简介 RabbitMQ 的消息发送流程&#xff1a; producer 将消息发送给 broker&#xff0c;consumer 从 broker 中获取消息并消费 那么在这里就涉及到了两种消息发送&#xff0c;即 producer 与 broker 之间和 consumer 与 broker 之间。 “消息确认” 讨论的是 consumer 与…

【51单片机用数码管显示流水灯的种类是按钮控制数码管加一和流水灯】2022-6-14

缘由 #include "REG52.h" unsigned char code smgduan[]{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0,64}; //共阴0~F消隐减号 unsigned char Js0, miao0;//中断计时 秒 分 时 毫秒 sbit k0P3^0; sbit k1P3^1; void smxs(u…

Android15 开机动画播放结束之后如何直接启动应用

问题背景 软件版本:Android15 在一些需求场景里面,需要开机动画播放结束立马去启动一个应用,下面介绍如何实现这种方案。 解决方案 首选我们需要知道开机动画播放结束之后的流程,这里会调用到wms里面,也就是一些enableScreen之类的函数,知道这个大概流程之后,再去对应…

AI实践:大模型痛点和解决方案讨论

大家好&#xff0c;我是星野&#xff0c;欢迎来到我的CSDN博客。在这个技术日新月异的时代&#xff0c;我们一起学习&#xff0c;共同进步。 今天想和大家分享的是大模型在实际应用中的痛点以及解决方案&#xff0c;特别是RAG&#xff08;检索增强生成&#xff09;技术。 大模…

Web前端工程化

Web前端工程化 前端工程化是指将软件工程的方法和原则应用到前端开发中&#xff0c;以提高开发效率、保证代码质量、便于团队协作和项目维护的一套体系化实践。以下是前端工程化的主要内容和实践&#xff1a; 核心组成部分 1. 模块化开发 JavaScript模块化&#xff1a;Comm…

Java 原生 HTTP Client

​介绍 Java 原生 HttpClient 是从 Java 11 开始引入的标准库&#xff0c;用于简化 HTTP 请求的发送与响应处理。它支持同步和异步请求&#xff0c;并内置对 HTTP/1.1 和 HTTP/2 协议的支持。HttpClient 提供了易用的 API 来设置请求头、请求体、处理响应以及配置 SSL/TLS 加密…

【C语言刷题】第十天:加量加餐继续,代码题训练,融会贯通IO模式

&#x1f525;个人主页&#xff1a;艾莉丝努力练剑 ❄专栏传送门&#xff1a;《C语言》、《数据结构与算法》、C语言刷题12天IO强训、LeetCode代码强化刷题 &#x1f349;学习方向&#xff1a;C/C方向 ⭐️人生格言&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为…

【WEB】Polar靶场 6-10题 详细笔记

六.jwt 这题我又不会写 先来了解下jwt **JWT&#xff08;JSON Web Token&#xff09;**是一种基于JSON的开放标准&#xff08;RFC 7519&#xff09;&#xff0c;主要用于在网络应用环境间传递声明信息。JWT通常用于身份验证和信息交换&#xff0c;确保在各方之间安全地传输信…

高阶亚马逊运营秘籍:关键词矩阵打法深度解析与应用

当竞争对手还在为单个大词竞价厮杀时&#xff0c;头部卖家已悄然构建了一张覆盖数千长尾关键词的隐形网络&#xff0c;精准触达每一个细分需求&#xff0c;以更低的成本撬动更高的转化率在亚马逊流量红利消退、广告成本高企的2025年&#xff0c;传统“爆款关键词”打法已显疲态…

【问题解决】org.springframework.web.util.NestedServletException Handler dispatch failed;

详细异常信息&#xff1a; org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter at org.springframework.web.servlet.DispatcherServlet.doDispatch(Disp…

【已解决】mac 聚焦搜索设置了edge 的地址栏搜索为google,还是跳转到百度

问题详情&#xff1a;在macbook的聚焦搜索中点击edge搜索的时候&#xff0c;跳转到了百度&#xff0c;即使已经将地址栏的搜索引擎设置为了goole&#xff0c;但是还是会跳转到百度。解决方案&#xff1a;1、打开safari浏览器。&#xff08;看清了&#xff0c;是打开Safari&…

MimicMotion 让你的图片动起来

MimicMotion 是由腾讯公司推出的一款人工智能人像动态视频生成框架。可以模仿视频动作再让图片模仿动作姿态&#xff0c;最后生成视频。 MimicMotion 的核心在于其置信度感知的姿态引导技术&#xff0c;确保视频帧的高质量和时间上的平滑过渡。 以前咱们也手搭过Animate-X让图…

云计算考核 - 分析电子银行需求采用微服务架构对系统进行设计

二、使用的技术以及分析 微服务&#xff08;Microservices&#xff09;是一种架构风格&#xff0c;一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署&#xff0c;各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在…

Ionic 安装使用教程

一、Ionic 简介 Ionic 是一个基于 Web 技术&#xff08;HTML、CSS、JavaScript&#xff09;的跨平台移动应用开发框架&#xff0c;结合 Angular、React 或 Vue 可快速构建 iOS 和 Android 应用。Ionic 提供丰富的 UI 组件、命令行工具及原生插件封装&#xff0c;广泛用于混合应…

渗透测试 - 简介

Web渗透测试简介 Web渗透测试&#xff08;Penetration Testing&#xff09;是一种模拟黑客攻击的安全评估方法&#xff0c;旨在发现Web应用程序中的漏洞&#xff0c;帮助开发者修复问题并提升系统安全性。它涉及主动测试目标系统&#xff08;如网站或API&#xff09;的弱点&am…

云原生AI研发体系建设路径

当AI遇上云原生&#xff0c;就像咖啡遇上牛奶&#xff0c;总能擦出不一样的火花 ☕️ &#x1f4cb; 文章目录 引言&#xff1a;为什么要建设云原生AI研发体系整体架构设计&#xff1a;搭建AI研发的"乐高积木"技术栈选择&#xff1a;选择合适的"武器装备"…