TypeScript 封装 Axios 1.7.7
随着Axios版本的不同,类型也在改变,以后怎么写类型?


yarn add axios
1. 封装Axios
将Axios封装成一个类,同时重新封装request方法
- 重新封装request有几个好处:
- 所有的请求将从我们定义的requet请求中发送,这样以后更换Axios工具,只需要将request方法重写就可以。
- 便于对请求的请求体和返回数据做拦截
- 方便统一配置请求的config
- 最基础版本
import axios from "axios";
import type { AxiosInstance } from "axios";class MyAxios {instance: AxiosInstance;constructor(config: AxiosRequestConfig) {this.instance = axios.create(config);}
// 重新封装axios的request方法async request(config: AxiosRequestConfig) {return await this.instance.reques(config)}
}
export default MyAxios;
- 发送请求
import MyAxios from "./request";
import { BASE_URL, TIME_OUT} from "./config"; // 配置文件const myRequest1 = new MyAxios({baseURL: BASE_URL,timeout: TIME_OUT,
});myRequest1.request({url: "/XXXXX",}).then((res) => {// res为成功后返回的结果});
2. 加入全局拦截器
- 加入全局拦截器后封装的Axios,调用方法与上面保持一致
import axios from "axios";
import type { AxiosInstance } from "axios";class MyAxios {instance: AxiosInstance;constructor(config: AxiosRequestConfig) {// 创建axios的实例this.instance = axios.create(config);// 全局请求拦截器this.instance.interceptors.request.use((config) => {// "全局请求拦截器:请求成功");return config;},(error) => {// ("全局请求拦截器:请求失败");return error;});// 全局响应拦截器this.instance.interceptors.response.use((res) => {// ("全局响应拦截器:响应成功");// res中含有axios中的很多东西,res.data :服务器返回的结果,return res.data;},(error) => {// ("全局响应拦截器:响应失败");return error;});}async request(config: AxiosRequestConfig) {return await this.instance.request(config)}
}export default MyAxios;
- 发送请求
import MyAxios from "./request";
import { BASE_URL, TIME_OUT} from "./config"; // 配置文件const myRequest1 = new MyAxios({baseURL: BASE_URL,timeout: TIME_OUT,
});myRequest1.request({url: "/XXXXX",}).then((res) => {// res变成了服务器发送会的数据,全局响应拦截器把Axios带的一些数据去掉了});
3. 加入域拦截器
域拦截器是我自己想的名字,也可以说是实例拦截器
在实例中定义拦截方法
- 拦截的范围是一个
baseURL,所以我称它为域拦截- 因为定义在一个
new MyAxios实例中,也可以说是实例拦截器
- 给拦截器定义类型
import type { AxiosRequestConfig } from "axios";// 自定义拦截器中的方法的类型
interface interceptorsFunction {requestOnFulfilled?: (config: any) => any; // 请求成功requestOnRejected?: (error: any) => any; // 请求失败responseOnFulfilled?: (res: any) => any; // 响应成功responseOnRejected?: (error: any) => any; // 响应失败
}
// 自定义拦截器类型。这里扩展了AxiosRequestConfig类型
interface MyAxiosRequestConfig extends AxiosRequestConfig {MyInterceptors?: interceptorsFunction;
}export { MyAxiosRequestConfig };
- 在实例中实现拦截器的方法
import MyAxios from "./request";
import { BASE_URL, TIME_OUT } from "./config";
import type { MyAxiosRequestConfig } from "./type";const myRequest2 = new MyAxios({baseURL: BASE_URL, timeout: TIME_OUT,// 域拦截器。给axios发送的自定义拦截器需要执行的功能MyInterceptors: {requestOnFulfilled: (config) => {// ("自定义请求拦截器:请求成功");return config},requestOnRejected: (error) => {// ("自定义请求拦截器:请求失败");return error},responseOnFulfilled: (res) => {// ("自定义响应拦截器:响应成功");return res},responseOnRejected: (error) => {// ("自定义响应拦截器:响应失败");return error}}
})
// 发送请求
myRequest.myRequest2.request({url: "XXXXXX",}).then((res) => {// (res);});
- 封装Axois
import axios from "axios";
import type { AxiosInstance } from "axios";
// 导入自定义拦截器的类型
import type { MyAxiosRequestConfig } from "./type";class MyAxios {instance: AxiosInstance;constructor(config: MyAxiosRequestConfig) {this.instance = axios.create(config);// 全局请求拦截器this.instance.interceptors.request.use((config) => {// ("全局请求拦截器:请求成功");return config;},(error) => {// ("全局请求拦截器:请求失败");return error;});// 全局响应拦截器this.instance.interceptors.response.use((res) => {// ("全局响应拦截器:响应成功");return res.data;},(error) => {// ("全局响应拦截器:响应失败");return error;});// 请求中自定义的拦截器:实例的拦截器// 判断config中是否有自定义的拦截器if (config.MyInterceptors) {// 把config中传过来的方法,绑定到实例上this.instance.interceptors.request.use(config.MyInterceptors.requestOnFulfilled,config.MyInterceptors.requestOnRejected);this.instance.interceptors.response.use(config.MyInterceptors.responseOnFulfilled,config.MyInterceptors.responseOnRejected);}}async request(config: AxiosRequestConfig<T>) {return await this.instance.request(config)}
}export default MyAxios;
4. 关于类型
requestOnFulfilled?: (config: any) => any; // 请求成功
定义拦截器类型中requestOnFulfilled类型,看的教学视频中config的类型是AxiosRequestConfig,我设置后死活报错,看了一下axios的类型定义文件中这里是InternalAxiosRequestConfig,这里就涉及axios的版本问题了,所以我觉得还是any安全,万一明天更新版本又换了类型,这个代码就不通用了

5. 一次性拦截器
- 这又是我自己起的名字,这个拦截器针对具体的一个请求
例如:域 http:// 10.1.2.3:8000下面有很多资源,比如有/api/img、/api/text,一次性拦截器就是针对域下面的资源的,可能/api/img需要拦截器工作,而/api/text不需要拦截器,所以每个资源对拦截器的需求和功能是不一样的
- 封装Axios,主要是对request请求的改动,其他地方没有改动,省略代码,这个拦截器虽然是起到了拦截器的效果,其实就是引入了一段代码
import axios from "axios";
import type { AxiosInstance } from "axios";
// 导入自定义拦截器的类型
import type { MyAxiosRequestConfig } from "./type";class MyAxios {instance: AxiosInstance;constructor(config: MyAxiosRequestConfig) {this.instance = axios.create(config);// 全局请求拦截器// 全局响应拦截器// 请求中自定义的拦截器:实例的拦截器}async request(config: MyAxiosRequestConfig) {// config中是否定义了requestOnFulfilled这个方法if (config.MyInterceptors?.requestOnFulfilled) {// 如果有这个方法,把config对象处理一下config = config.MyInterceptors.requestOnFulfilled(config);}return await this.instance.request(config) // request方法返回Promise.then((res) => { // Promise是成功状态返回的res,如果需要处理就处理一下子if (config.MyInterceptors?.responseOnFulfilled) {res = config.MyInterceptors.responseOnFulfilled(res);}return res;}).catch((error) => { // Promise是失败状态或者异常,处理一下子if (config.MyInterceptors?.responseOnRejected)error = config.MyInterceptors.responseOnRejected(error);return error;});}
}export default MyAxios;
- 发送请求
const myRequest1 = new MyAxios({baseURL: BASE_URL,timeout: TIME_OUT,
});
// 发送请求
myRequest1.request({url: "XXXXXX",// 定义一次性拦截器,只对 url: "XXXXX" 起效MyInterceptors: {requestOnFulfilled: (config) => {// ("一次性拦截器,请求成功拦截");return config;},responseOnFulfilled: (res) => {// ("一次性拦截器,响应成功拦截");return res;},responseOnRejected: (res) => {// ("一次性拦截器,响应失败拦截");return res;},},}).then((res) => {// (res);});
- 拦截器的类型定义与域拦截器中的一样就不重复了
6. 总结
- 全局拦截器:只要使用Axios发送请求就会执行
- 域拦截器:对实例中的一个
baseURL(http://10.1.2.3:8080)负责 - 一次性拦截器:对单个request请求负责(/api/img、/api/text)
7. 以下是加上泛型定义和其他请求的Axios封装的完整版本
拦截器的类型定义
// /request/type.ts 文件
import type { AxiosRequestConfig } from "axios";// 自定义拦截器中的方法的类型
interface interceptorsFunction<T = any> {requestOnFulfilled?: (config: any) => any; // 请求成功requestOnRejected?: (error: any) => any; // 请求失败responseOnFulfilled?: (res: T) => T; // 响应成功responseOnRejected?: (error: any) => any; // 响应失败
}
// 自定义拦截器类型
interface MyAxiosRequestConfig<T = any> extends AxiosRequestConfig {MyInterceptors?: interceptorsFunction<T>;
}export type { MyAxiosRequestConfig };
常量的定义
- 这里的cLog是方便调试,不用的时候在这里设置为false就不打印了,打印的东西多了,看的眼花
// /config/index.ts
export const cLog = (message:any)=>{// if (process.env.NODE_ENV !== 'production') return// if (0) return console.log(message)
}export const BASE_URL = "http://XXXXXXXXXX"
export const TIME_OUT = 10000
封装后的Axios
// /request/index.ts
import axios from "axios";
import type { AxiosInstance } from "axios";
import { cLog } from "../config";
// 导入自定义拦截器的类型
import type { MyAxiosRequestConfig } from "./type";class MyAxios {instance: AxiosInstance;constructor(config: MyAxiosRequestConfig) {this.instance = axios.create(config);// 全局请求拦截器this.instance.interceptors.request.use((config) => {cLog("全局请求拦截器:请求成功");return config;},(error) => {cLog("全局请求拦截器:请求失败");return error;});// 全局响应拦截器this.instance.interceptors.response.use((res) => {cLog("全局响应拦截器:响应成功");return res.data;},(error) => {cLog("全局响应拦截器:响应失败");return error;});// 请求中自定义的拦截器:实例的拦截器if (config.MyInterceptors) {this.instance.interceptors.request.use(config.MyInterceptors.requestOnFulfilled,config.MyInterceptors.requestOnRejected);this.instance.interceptors.response.use(config.MyInterceptors.responseOnFulfilled,config.MyInterceptors.responseOnRejected);}}async request<T = any>(config: MyAxiosRequestConfig<T>) {if (config.MyInterceptors?.requestOnFulfilled) {config = config.MyInterceptors.requestOnFulfilled(config);}return await this.instance.request<any, T>(config).then((res) => {if (config.MyInterceptors?.responseOnFulfilled) {res = config.MyInterceptors.responseOnFulfilled(res);}return res;}).catch((error) => {if (config.MyInterceptors?.responseOnRejected)error = config.MyInterceptors.responseOnRejected(error);return error;});}get<T = any>(config: MyAxiosRequestConfig<T>) {return this.request({ ...config, method: "get" });}post<T = any>(config: MyAxiosRequestConfig<T>) {return this.request({ ...config, method: "post" });}delete<T = any>(config: MyAxiosRequestConfig<T>) {return this.request({ ...config, method: "delete" });}put<T = any>(config: MyAxiosRequestConfig<T>) {return this.request({ ...config, method: "put" });}patch<T = any>(config: MyAxiosRequestConfig<T>) {return this.request({ ...config, method: "patch" });}
}export default MyAxios;
实例Axios
- myRequest1:只有全局拦截器
- myRequest2:有全局拦截器和域拦截器
// index.ts
import MyAxios from "./request";
import { BASE_URL, TIME_OUT, cLog } from "./config";const myRequest1 = new MyAxios({baseURL: BASE_URL,timeout: TIME_OUT,
});const myRequest2 = new MyAxios({baseURL: BASE_URL,timeout: TIME_OUT,// 给axios发送的自定义拦截器需要执行的功能MyInterceptors: {requestOnFulfilled: (config) => {cLog("自定义请求拦截器:请求成功");return config},requestOnRejected: (error) => {cLog("自定义请求拦截器:请求失败");return error},responseOnFulfilled: (res) => {cLog("自定义响应拦截器:响应成功");return res},responseOnRejected: (error) => {cLog("自定义响应拦截器:响应失败");return error}}
})
export default { myRequest1,myRequest2 };
实际发送请求
- 以上都可以作为固定的使用,下面的部分就是我们每次要发送请求时编写的
// main.js
import myRequest from "../index";
import { cLog } from "../config";myRequest.myRequest1.request({url: "XXXXX",}).then((res) => {cLog(res);});myRequest.myRequest2.request({url: "XXXXX",}).then((res) => {cLog(res);});myRequest.myRequest2// 这里的类型是服务器返回数据的类型,感觉复杂这里用any// 为什么这里的类型是服务器返回的数据类型?在全局拦截器中返回的是res.data// 如果在其他拦截器中没有对res做出改变。这里应该是AxiosResponse类型.request<类型>({ url: "XXXXX",// 一次性拦截器MyInterceptors: {requestOnFulfilled: (config) => {cLog("一次性拦截器,请求成功拦截");return config;},responseOnFulfilled: (res) => {cLog("一次性拦截器,响应成功拦截");return res;},responseOnRejected: (res) => {cLog("一次性拦截器,响应失败拦截");return res;},},}).then((res) => {cLog(res);});
8. 拦截器的执行顺序
- 只有全局拦截器
全局请求拦截器:请求成功
全局响应拦截器:响应成功
- 有全局拦截器和域拦截器
自定义请求拦截器:请求成功
全局请求拦截器:请求成功
全局响应拦截器:响应成功
自定义响应拦截器:响应成功
- 全局、域、一次性拦截器
一次性拦截器,请求成功拦截
自定义请求拦截器:请求成功
全局请求拦截器:请求成功
全局响应拦截器:响应成功
自定义响应拦截器:响应成功
一次性拦截器,响应成功拦截
9. 目录结构

相关文章:
TypeScript 封装 Axios 1.7.7
随着Axios版本的不同,类型也在改变,以后怎么写类型? yarn add axios1. 封装Axios 将Axios封装成一个类,同时重新封装request方法 重新封装request有几个好处: 所有的请求将从我们定义的requet请求中发送ÿ…...
【数据结构】【链表代码】移除链表元素
移除链表元素 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* removeElements(struct ListNode* head, int val) { // 创建一个虚拟头节点,以处理头节点可能被删除的情况 struct…...
作文-杭州游记
杭州的学习与游历 在这个风景如画的城市——杭州,学习信息学的日子如同西湖的水,清澈而又深邃。在这里,课堂与自然的交融、技术与文化的碰撞,构成了一幅独特的画卷。 学习之旅 信息学的课程不仅仅是对代码和算法的解析࿰…...
降压芯片TPS54821
降压芯片TPS54821 介绍 价格低廉,只需1.5元。是一个同步整流降压BUCK电路。MOS管内置。输入电压为4.5V至17V,输出电压为0.6V到15V,输出电流最大到8A。是QFN封装,焊接时有些许困难。得益于QFN封装,其引线电感非常的小…...
YOLO v1详解解读
🚀 在此之前主要介绍了YOLO v5源码的安装和使用(YOLO v5安装教程),接下来将探索YOLO的实现原理,作为一个金典的单阶段目标检测算法,应该深度的理解它的构建思想;所以本系列文章将从LOVO v1出发到…...
【动态规划-最长公共子序列(LCS)】【hard】【科大讯飞笔试最后一题】力扣115. 不同的子序列
给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数,结果需要对 10^9 7 取模。 示例 1: 输入:s “rabbbit”, t “rabbit” 输出:3 解释: 如下所示, 有 3 种可以从 s 中得到 “rabbit”…...
深入理解 JavaScript 中的 void`运算符和 yield*表达式
深入理解 JavaScript 中的 void 运算符和 yield* 表达式 在 JavaScript 中,void 运算符和 yield* 表达式是两个功能独特但常被忽视的运算符。本文将详细介绍它们的用法和应用场景,帮助您更好地理解和运用这两个运算符。 目录 void 运算符概述void 运算…...
第四节——从深层剖析指针(让你不再害怕指针)
文章目录 1. 字符指针变量剑指offer例题 2. 数组指针变量2.1 数组指针变量是什么?2.2 数组指针变量怎么初始化 3. ⼆维数组传参的本质代码实现 4. 函数指针变量4.1 函数指针变量的创建4.3 两段有趣的代码4.3.1 typedef 关键字 5. 函数指针数组的定义 1. 字符指针变量…...
openpnp - 吸嘴校正失败的opencv参数分析
文章目录 openpnp - 吸嘴校正失败的opencv参数分析概述笔记阶段验证 - N2吸嘴校验完NT1NT2 阶段验证 - 底部相机高级校验完NT1NT2 参数比对保存 “阶段验证 - N2吸嘴校验完” 的NT1/NT2图像重建参数检测环境NT1ok的3个参数值NT1err的3个参数值NT2ok的3个参数值NT2err的3个参数值…...
【Python】Marmir 使用指南:Python 驱动的电子表格生成器
Marmir 是一个由 Python 驱动的电子表格生成工具,专门用于将 Python 数据结构(如字典、列表等)转换为电子表格文件(如 Excel)。Marmir 的设计目标是提供比传统电子表格库(如 xlwt)更强大和灵活的…...
深入理解 JavaScript 事件循环机制:单线程中的异步处理核心
深入理解 JavaScript 事件循环机制:单线程中的异步处理核心 JavaScript 是一门单线程的编程语言,也就是说它在同一时间只能执行一个任务。然而,现代 Web 应用经常需要处理大量的异步操作,如用户输入、网络请求、定时器等。为了确…...
Stream流的终结方法(二)——collect
1.Stream流的终结方法 2. collect方法 collect方法用于收集流中的数据放到集合中去,可以将流中的数据放到List,Set,Map集合中 2.1 将流中的数据收集到List集合中 package com.njau.d10_my_stream;import java.util.*; import java.util.f…...
【C语言系统编程】【第一部分:操作系统知识】1.1.操作系统原理
第一部分:操作系统知识 1.1 操作系统原理 1.1.1 进程管理 1.1.1.1 进程的概念与生命周期 进程是程序在计算机中的一次执行实例,包括了程序的代码、数据、以及运行的上下文环境。进程管理是操作系统的核心任务之一。 作用:管理所有执行中…...
基于Java+VUE+echarts大数据智能道路交通信息统计分析管理系统
大数据智能交通管理系统是一种基于Web的系统架构,通过浏览器/服务器(B/S)模式实现对城市交通数据的高效管理和智能化处理。该系统旨在通过集成各类交通数据,包括但不限于车辆信息、行驶记录、违章情况等,来提升城市管理…...
leetcode-42. 接雨水 单调栈
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表…...
ThinkPHP和PHP的区别
文章目录 ThinkPHP和PHP的区别一、引言二、PHP简介1、第一步1.1、示例代码 三、ThinkPHP简介2、第二步2.1、特点2.2、示例代码 四、总结 ThinkPHP和PHP的区别 一、引言 在Web开发领域,PHP是一种广泛使用的开源脚本语言,而ThinkPHP则是一个基于PHP的MVC…...
clientWidth,offsetWidth,scrollHeight
clientWidth: offsetWidth: scrollHeight:...
SVN版本回退
SVN 版本回退三种方法: Update item to this version 假设我们的项目文件一共有8个版本,它版本号分别是1,2,3,4,5,6,7,8。 这个选项的作用是将文件版本更新到对应所选的…...
IDEA关联Tomcat
一、Tomcat服务器 web服务器,就是运行web项目的容器 即运行java代码的一个容器 webapp(web应用程序) --> 就是我们写的javaweb项目 Tomcat 是Apache 软件基金会(Apache Software Foundation)下的一个核心项目,免费开源、并支持Servlet 和J…...
MongoDB mongoose 的 save、insert 和 create 方法的比较
目录 save 方法 insert 方法 create 方法 使用会话和事务 总结 在本文中,我们将介绍 MongoDB 中使用 mongoose 操作 数据库时的三种常见方法:save、insert 和 create。这些方法可以用于将数据存储到 MongoDB 数据库中,并且在一定程度上具…...
Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
