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

工具类-基于 axios 的 http 请求工具 Request

基于 axios 的 http 请求工具

基于 axios 实现一个 http 请求工具,支持设置请求缓存和取消 http 请求等功能

首先实现一个 简单的 http 请求工具

import axios, {AxiosError,AxiosInterceptorManager,AxiosRequestConfig,AxiosResponse,
} from 'axios';// 接口返回的数据格式
interface ResponseData<T = any> {code: number;data: T;message: string;
}// 发起请求的参数
interface RequestConfig extends AxiosRequestConfig {url: string;
}class Request {private instance = axios.create({headers: {'Content-Type': 'application/json;charset=utf-8',},withCredentials: true,});constructor() {// 设置请求拦截const request = this.instance.interceptors.request as AxiosInterceptorManager<RequestConfig>;request.use(config => this.handleRequest(config));// 设置响应拦截const { response } = this.instance.interceptors;response.use(config => this.handleResponse(config));}// 请求拦截private handleRequest(config: RequestConfig): RequestConfig {// TODO: 请求前拦截处理 loading, url 或请求头等return config;}// 响应拦截private handleResponse(response: AxiosResponse<Blob>): AxiosResponse {// TODO: 响应后拦截处理 loading, 状态码或数据等return response;}// 错误拦截: 处理错误private handleError(error: AxiosError) {// TODO: 请求出错时的处理return Promise.reject(error);}async request<T = any>(requestConfig: RequestConfig) {const { method = 'GET', ...config } = requestConfig;try {const response = await this.instance.request<ResponseData<T>>({ ...config, method });return response.data;} catch (error) {this.handleError(error as AxiosError);throw error; // 将异常重新抛出去,不要吃掉异常}}get<T = any>(requestConfig: RequestConfig) {return this.request<T>({ method: 'GET', ...requestConfig });}post<T = any>(requestConfig: RequestConfig) {return this.request<T>({ method: 'POST', ...requestConfig });}put<T = any>(requestConfig: RequestConfig) {return this.request<T>({ method: 'PUT', ...requestConfig });}patch<T = any>(requestConfig: RequestConfig) {return this.request<T>({ method: 'PATCH', ...requestConfig });}delete<T = any>(requestConfig: RequestConfig) {return this.request<T>({ method: 'DELETE', ...requestConfig });}
}

封装 Request 类,将 axios 示例缓存在 instance 中,在 Request 类构造函数中设置拦截器。封装 request 函数作为发起请求的函数, 接收泛型表示接口返回的 data 字段的数据类型。增加 get、post、patch 等别名函数,代替传入 method。

示例

interface ResData {name: string;age: number;
}const request = new Request()
const result = await request.get<ResData>({url: '/user-info',params: {id: '12138',},
});

增加拦截器的处理

在拦截器中同意处理一些东西,比如在请求拦截中发起全局 loading,在响应拦截中处理数据等等

loading

import axios, {AxiosError,AxiosInterceptorManager,AxiosRequestConfig,AxiosResponse,
} from 'axios';// 接口返回的数据格式
interface ResponseData<T = any> {code: number;data: T;message: string;
}// 发起请求的参数
interface RequestConfig extends AxiosRequestConfig {url: string;// 请求时是否需要发起 loaing,默认为 trueloading?boolean}class Request {...constructor() {// 设置请求拦截const request = this.instance.interceptors.request as AxiosInterceptorManager<RequestConfig>;request.use(config => this.handleRequestLoading(config));request.use(config => this.handleRequest(config));// 设置响应拦截const { response } = this.instance.interceptors;response.use(config => this.handleResponseLoading(config));response.use(config => this.handleResponse(config));}// 请求拦截: 处理 loadingprivate handleRequestLoading(config: RequestConfig): RequestConfig {const { loading = true, url } = config;if (loading) openLoading(); // openLoading 是开启全局 Loading 的方法return config;}// 响应拦截: 处理 loadingprivate handleResponseLoading(response: AxiosResponse<Blob>): AxiosResponse {const {config: { url, loading },} = response;closeLoading(); // closeLoading 是关闭全局 Loading 的方法return response;}// 请求拦截private handleRequest(config: RequestConfig): RequestConfig {// TODO: 请求前拦截处理 loading, url 或请求头等return config;}// 响应拦截private handleResponse(response: AxiosResponse<Blob>): AxiosResponse {// TODO: 响应后拦截处理 loading, 状态码或数据等return response;}// 错误拦截: 处理错误private handleError(error: AxiosError) {// TODO: 请求出错时的处理return Promise.reject(error);}...
}export default Request;

上面的代码分别在请求拦截和响应拦截中获取 requestConfig 中的 loading 字段的值,如果 loading 的值为 true,则开启/关闭全局的 loading。

但是这样做有一个缺陷,全局 loading 一般都是单例的,如果同时有两个需要 loading 的请求发起,那么当一个请求完成时会关闭 loading,此时另一个请求还未完成,这样就不符合实际需求了

我们可以设计一个 Loading 类来管理 loading 状态

class Loading {private loadingApiList: string[] = [];open(key: string) {if (this.loadingApiList.length === 0) openLoading();this.loadingApiList.push(key);}close(key: string) {const index = this.loadingApiList.indexOf(key);if (index > -1) this.loadingApiList.splice(index, 1);if (this.loadingApiList.length === 0) closeLoading();}
}
  • Loaing 类使用了 loadingApiList 将正在进行且需要 loading 的请求的 url 缓存起来。
  • 每次请求需要 loading 时,调用 Loading 类的 open 函数,open 函数会判断当前是否有还在 Loading 的请求,如果没有则调起 loading,将请求的 url 存入 loadingApiList
  • 当请求结束时调用 Loading 类的 close 函数,close 函数会将该请求的 url 从 loadingApiList 中删除,再判断当前是否还有请求需要 Loading,如果没有则关闭 loading
class Request {...constructor(){...this.loading = new Loagn();}// 请求拦截: 处理 loadingprivate handleRequestLoading(config: RequestConfig): RequestConfig {const { loading = true, url } = config;if (loading) this.loading!.open(url);return config;}// 响应拦截: 处理 loadingprivate handleResponseLoading(response: AxiosResponse<Blob>): AxiosResponse {const {config: { url },} = response;this.loading!.close(url!);return response;}...
}

注:使用 Class 类来处理 loading 是基于业务系统上的其他需要,或为了更优雅的应对其他复杂情况,并非一定要使用 Class 写法,用 hooks 或工具函数也可以

处理 http 响应状态和业务响应状态

// http 状态码对应的 message
const RESPONSE_STATUS_MESSAGE_MAP: Record<number | 'other', string> = {400: '客户端请求的语法错误,服务器无法理解。',401: '请求未经授权。',403: '服务器是拒绝执行此请求。',404: '请求不存在。',405: '请求方法不被允许。',500: '服务器内部错误,无法完成请求。',501: '服务器不支持当前请求所需要的功能。',502: '作为网关或代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。',503: '由于临时的服务器维护或者过载,服务器当前无法处理请求。',504: '作为网关或者代理服务器尝试执行请求时,没有从上游服务器收到及时的响应。',other: '未知错误, 请稍后尝试',
};class Request {...constructor(){...const { response } = this.instance.interceptors;response.use(config => this.handleResponseLoading(config));response.use(config => this.handleResponseStatus(config),error => this.handleError(error));}// 请求拦截: http 响应状态和业务响应状态private handleResponseStatus(response: AxiosResponse<ResponseData>): Promise<AxiosResponse> {const { status, data } = response;if (status !== 200) {const statusMessage = RESPONSE_STATUS_MESSAGE_MAP[status] || '服务器错误, 请稍后尝试';return Promise.reject(new AxiosError('', response.statusText, response.config, response.request, response));}// 业务状态码根据自身系统接口规范处理const { code } = data || {};if (code === 401) {// 401 一般为未登录或 token 过期处理,这里一般处理为退出登录和 refreshreturn this.refresh(response); // refresh 函数会实现 token 刷新并重新请求,这里可以忽略}// 一般非 200 未错误状态,显示提示消息if (code !== 200) {const { message } = data;// 将接口的 message 传递给 AxiosErrorreturn Promise.reject(new AxiosError(message, response.statusText, response.config, response.request, response));}return Promise.resolve(response);}// 错误拦截: 处理错误,处理通知消息private handleError(error: AxiosError) {this.loading.close(error.config!.url!);// 判断请求是否被取消,若果被取消不需要处理通知消息if (axios.isCancel(error)) return error;const { status, message } = error as AxiosError;// 如果是 http 错误,使用状态码匹配错误信息,否则使用接口返回的 mesageconst _message = status === 200 ? message : RESPONSE_STATUS_MESSAGE_MAP[status!];sendMessage(_message || RESPONSE_STATUS_MESSAGE_MAP.other); // 发送错误信息的 messagereturn error;}...
}

实现取消请求功能 – abort

未完待续…

实现 http 缓存功能 – cache

未完待续…uq

相关文章:

工具类-基于 axios 的 http 请求工具 Request

基于 axios 的 http 请求工具 基于 axios 实现一个 http 请求工具&#xff0c;支持设置请求缓存和取消 http 请求等功能 首先实现一个 简单的 http 请求工具 import axios, {AxiosError,AxiosInterceptorManager,AxiosRequestConfig,AxiosResponse, } from axios;// 接口返回…...

WPF的基础控件详解

WPF的基础控件详解 在WPF学习中 基本控件是最简单也是最基础的东西。也是很初学者容易忽略的 本此笔记教程主要针对WPF中基础控件使用和应用进行手把手教学&#xff0c;如果学习了此笔记对你有帮助记得一键三连哦~~~~ TextBlock 基本用法 长字串处理 LineBreak标籤在指定的地…...

qt学习:截图+键盘事件

效果 生成一个透明无边框全屏的窗口&#xff0c;然后按ctrlb键就可以选择区域进行截图保存 步骤 新建一个项目新建一个ctrlb类继承QMainWindow新建一个CaptureScreen类继承QWidget在main中启动ctrlb类 代码 ctrlb类.cpp #include "ctrlb.h" #include "cap…...

Scala中Arry

import scala.collection.mutable.ArrayBuffer //Arry:数组 //可修改的&#xff1a;ArryBuffer //不可修改的&#xff1a;Arryobject Test_1118_2 {//可修改的&#xff1a;ArrayBufferdef main(args: Array[String]): Unit {//1.新建val arr1ArrayBuffer(1,2,3)//2.添加arr14a…...

学习threejs,使用AnimationMixer实现变形动画

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.AnimationMixer 动画…...

两大新兴开发语言大比拼:Move PK Rust

了解 Move 和 Rust 的差异有助于开发者根据项目的具体需求选择最合适的语言。选择不恰当的语言可能会导致项目后期出现技术债务。不同语言有其独特的优势。了解 Move 和 Rust 的差异可以帮助开发者拓展技术视野&#xff0c;发现不同语言在不同领域的应用潜力。 咱们直奔主题&a…...

基于一种基于OCR图像识别技术的发票采集管理系统及方法

本发明涉及了一种基于OCR图像识别技术的发票采集管理系统及方法&#xff0c;该系统的发票信息采集单元采集发票图片信息数据&#xff0c;OCR图像识别单元基于OCR图像识别技术并结合人工智能深度学习算法对发票图片信息数据进行识别读取以获得OCR图像识别结果&#xff0c;发票信…...

基于深度学习的车牌检测系统的设计与实现(安卓、YOLOV、CRNNLPRNet)+文档

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…...

JavaWeb——JS、Vue

目录 1.JavaScript a.概述 b.引入方式 c.JS的基础语法 d.JS函数 e.JS对象 f.JS事件监听 2.Vue a.概述 b.Vue常用指令 d.生命周期 1.JavaScript a.概述 JavaScript是一门跨平台、面向对象的脚本语言。是用来控制网页行为的&#xff0c;它能使网页可交互。JavaScript和…...

Springboot 整合 Java DL4J 构建股票预测系统

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…...

ATmaga8单片机Pt100温度计源程序+Proteus仿真设计

目录 1、项目功能 2、仿真图 ​3、程序 资料下载地址&#xff1a;ATmaga8单片机Pt100温度计源程序Proteus仿真设计 1、项目功能 设计Pt100铂电阻测量温度的电路&#xff0c;温度测量范围是0-100摄氏度&#xff0c;要求LCD显示。画出电路图&#xff0c;标注元器件参数&am…...

FPGA通过MIPI CSI-2发送实时图像到RK3588,并HDMI显示

介绍FPGA通过MIPI CSI-2发送实时图像到RK3588&#xff0c;并HDMI显示。 FPGA本地产生动态图像模板&#xff0c;通过MIPI CSI-2接口发送到RK3588 MIPI CSI接口。RK3588注册成相机后&#xff0c;调用接口并在HDMI显示器上显示。 1、RK3588驱动调试 查看Media controller信息 Med…...

ELK8.15.4搭建开启安全认证

安装 Elastic &#xff1a;Elasticsearch&#xff0c;Kibana&#xff0c;Logstash 另外安装一个收集器filebeat 通过二进制安装包进行安装 创建一个专门放elk目录 mkdir /elk/ mkdir /elk/soft下载 es 、kibana、Logstash、filebeat二进制包 cd /elk/softwget https://art…...

原生微信小程序中封装一个模拟select 下拉框组件

1.首先在components 里面设置组件名称&#xff1a;van-select&#xff08;随便取名字&#xff09;&#xff1b; 2.新建文件写代码&#xff1a; wxml&#xff1a; <view class"w100 select_all_view"><!-- 标题&#xff0c;可以没有 --><view class…...

商品管理系统引领时尚零售智能化升级 降价商品量锐减30%

根据贝恩咨询公司2024年发布的消费品报告&#xff0c;当前消费品行业正面临增长放缓、全球市场波动及消费者期望变化的巨大压力。为保持市场竞争力&#xff0c;企业需要重新审视其增长战略&#xff0c;重视可持续创新、数字化转型和运营敏捷性。企业必须灵活应对供应链中断和消…...

UE5 5.1.1创建C++项目,显示error C4668和error C4067

因为工作要求&#xff0c;没法使用最新 5.5版本的ue5 而是要用ue5.1和5.2版本。 但是我在安装下载了visual studio2022后&#xff0c;使用 ue5.1编辑器 创建C项目&#xff0c;爆出如下错误。 error C4668: ?????__has_feature?????ΪԤ?????꣬???0????…...

spring boot 集成 redis 实现缓存的完整的例子

Cacheable 注解是 Spring Cache 抽象的一部分&#xff0c;用于声明式地管理缓存。Cacheable 注解本身并不直接指定缓存的存储位置&#xff0c;而是依赖于配置的缓存管理器&#xff08;CacheManager&#xff09;来决定缓存数据的存储位置。 常见的缓存存储方式: 1、内存缓存&a…...

json-bigint处理前端精度丢失问题

问题描述&#xff1a;前后端调试过程中&#xff0c;有时候会遇到精度丢失的问题&#xff0c;比如后端给过来的id超过16位&#xff0c;就会出现精度丢失的情况&#xff0c;前端拿到的id与后端给过来的不一致。 解决方案&#xff1a; 1、安装 npm i json-bigint 2、在axios中配置…...

【算法】【优选算法】前缀和(下)

目录 一、560.和为K的⼦数组1.1 前缀和1.2 暴力枚举 二、974.和可被K整除的⼦数组2.1 前缀和2.2 暴力枚举 三、525.连续数组3.1 前缀和3.2 暴力枚举 四、1314.矩阵区域和4.1 前缀和4.2 暴力枚举 一、560.和为K的⼦数组 题目链接&#xff1a;560.和为K的⼦数组 题目描述&#x…...

Node.js 23 发布了!

Node.js 23 现已推出&#xff0c;带来了新功能、性能改进和更好的开发者体验。此次版本提升了兼容性和稳定性&#xff0c;提供了更多工具来构建高效的应用程序。 此外&#xff0c;Node.js 22 将在 10 月 29 日当周被提升为长期支持 (LTS) 版本&#xff0c;进入长期维护阶段&am…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...