TypeScript 封装 Axios 1.7.7

随着Axios版本的不同,类型也在改变,以后怎么写类型?
在这里插入图片描述
在这里插入图片描述

yarn add axios

1. 封装Axios

将Axios封装成一个类,同时重新封装request方法

  • 重新封装request有几个好处:
    1. 所有的请求将从我们定义的requet请求中发送,这样以后更换Axios工具,只需要将request方法重写就可以。
    2. 便于对请求的请求体和返回数据做拦截
    3. 方便统一配置请求的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. 加入域拦截器

域拦截器是我自己想的名字,也可以说是实例拦截器
在实例中定义拦截方法

  1. 拦截的范围是一个baseURL,所以我称它为域拦截
  2. 因为定义在一个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. 目录结构

在这里插入图片描述

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

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

相关文章

Vue3实现动态菜单功能

文章目录 0.效果演示1.搭建Vue3项目1.1 vite 脚手架创建 Vue3 项目1.2 设置文件别名1.3 安装配置 element-plus1.4 安装配置路由2.登录页面3.后台管理页面3.1 搭建后台框架3.2 左侧菜单栏3.3 header 用户信息3.4 主要内容3.5 footer4.配置静态路由5.记录激活菜单5.1 el-menu 绑…

卸载apt-get 安装的PostgreSQL版本

文章目录 卸载apt-get 安装的PostgreSQL版本查找已安装的PostgreSQL包卸载PostgreSQL&#xff1a;检查并删除残留文件验证卸载 卸载apt-get 安装的PostgreSQL版本 卸载通过apt-get安装的PostgreSQL 就版本&#xff0c;可以按照以下步骤进行。 查找已安装的PostgreSQL包 在卸…

信号处理快速傅里叶变换(FFT)的学习

FFT是离散傅立叶变换的快速算法&#xff0c;可以将一个信号变换到频域。有些信号在时域上是很难看出什么特征的&#xff0c;但是如果变换到频域之后&#xff0c;就很容易看出特征了。这就是很多信号分析采用FFT变换的原因。另外&#xff0c;FFT可以将一个信号的频谱提取出来&am…

StarRocks 中如何做到查询超时(QueryTimeout)

背景 本文基于 StarRocks 3.1.7 主要是分析以下两种超时设置的方式: SESSION 级别 SET query_timeout 10;SELECT sleep(20);SQL 级别 select /* SET_VAR(query_timeout10) */ sleep(20); 通过本文的分析大致可以了解到在Starrocks的FE端是如何进行Command的交互以及数据流走…

Java Web 之 Cookie 详解

在 JavaWeb 开发中&#xff0c;Cookie 就像网站给浏览器贴的小纸条&#xff0c;用于记录一些用户信息或状态&#xff0c;方便下次访问时识别用户身份或进行个性化服务。 也可以这么理解&#xff1a; 场景一&#xff1a;想象一下&#xff0c;你去一家咖啡店&#xff0c;店员认…

webpack信息泄露

先看看webpack中文网给出的解释 webpack 是一个模块打包器。它的主要目标是将 JavaScript 文件打包在一起,打包后的文件用于在浏览器中使用,但它也能够胜任转换、打包或包裹任何资源。 如果未正确配置&#xff0c;会生成一个.map文件&#xff0c;它包含了原始JavaScript代码的映…

VPN简述

文章目录 VPNVPN基础VPN类型 VPN VPN隧道安全 VPN基础 背景&#xff1a; 在网络传输中&#xff0c;绝大部分数据内容都是明文传输&#xff0c;存在很多安全隐患&#xff08;窃听、篡改、冒充&#xff09; 总部、分公司、办事处、出差人员、合作单位等需要访问总部网络资源 Vi…

富格林:警悟可信经验安全投资

富格林指出&#xff0c;黄金具有不错的投资价值&#xff0c;一直以来备受投资者的喜爱&#xff0c;近年来大家也纷纷加入现货黄金市场为己增值财富。但是要为投资安全护航的前提&#xff0c;是需要投资者使用合适可信的方法以及掌握相对应的投资技巧。下面富格林将总结以下可信…

【数学分析笔记】第4章第4节 复合函数求导法则及其应用(1)

4. 微分 4.4 复合函数求导法则及其应用 4.4.1 复合函数求导法则 【定理4.4.1】 u g ( x ) ug(x) ug(x)在 x x 0 xx_0 xx0​可导&#xff0c; g ( x 0 ) u ( 0 ) g(x_0)u(0) g(x0​)u(0)&#xff0c; y f ( u ) yf(u) yf(u)在 u u 0 uu_0 uu0​可导&#xff0c;则 y f …

SpringBoot+Redis+RabbitMQ完成增删改查

各部分分工职责 RabbitMQ负责添加、修改、删除的异步操作 Redis负责数据的缓存 RabbitMQ里面角色职责简单描述 RabbitMQ里面有几个角色要先分清以及他们的对应关系&#xff1a; 交换机、队列、路由键 交换机和队列是一对多 队列和路由键是多对多 然后就是消息的发送者&…

课设实验-数据结构-线性表-手机销售

题目&#xff1a; 代码&#xff1a; #include<stdio.h> #include<string.h> #define MaxSize 10 //定义顺序表最大长度 //定义手机结构体类型 typedef struct {char PMod[10];//手机型号int PPri;//价格int PNum;//库存量 }PhoType; //手机类型 //记录手机的顺序…

【HTTP(3)】(状态码,https)

【认识状态码】 状态码最重要的目的&#xff0c;就是反馈给浏览器:这次请求是否成功&#xff0c;若失败&#xff0c;则出现失败原因 常见状态码: 200:OK&#xff0c;表示成功 404:Not Found&#xff0c;浏览器访问的资源在服务器上没有找到 403:Forbidden&#xff0c;访问被…

springboot系列--web相关知识探索三

一、前言 web相关知识探索二中研究了请求是如何映射到具体接口&#xff08;方法&#xff09;中的&#xff0c;本次文章主要研究请求中所带的参数是如何映射到接口参数中的&#xff0c;也即请求参数如何与接口参数绑定。主要有四种、分别是注解方式、Servlet API方式、复杂参数、…

【案例】距离限制模型透明

开发平台&#xff1a;Unity 2023 开发工具&#xff1a;Unity ShaderGraph   一、效果展示 二、路线图 三、案例分析 核心思路&#xff1a;计算算式&#xff1a;透明值 实际距离 / 最大距离 &#xff08;实际距离 ≤ 最大距离&#xff09;   3.1 说明 | 改变 Alpha 值 在 …

计算机组成原理之无符号整数的表示和运算

无符号整数的表示 无符号整数的表示&#xff1a;无符号整数直接使用其二进制形式表示&#xff0c;所有位都是数值位&#xff0c;没有符号位。例如&#xff0c;一个8位的无符号整数可以表示的范围是从0&#xff08;00000000&#xff09;到255&#xff08;11111111&#xff09;。…

stm32f103调试,程序与定时器同步设置

在调试定时器相关代码时&#xff0c;注意到定时器的中断位总是置1&#xff0c;怀疑代码有问题&#xff0c;经过增大定时器的中断时间&#xff0c;发现定时器与代码调试并不同步&#xff0c;这一点对于调试涉及定时器的代码是非常不利的&#xff0c;这里给出keil调试stm32使定时…

自用Proteus(8.15)常用元器件图示和功能介绍(持续更新...)

文章目录 一、 前言二、新建工程&#xff08;以51单片机流水灯为例&#xff09;2.1 打开软件2.2 建立新工程2.3 创建原理图2.4 不创建PCB布版设计2.5 创建成功2.6 添加元器件2.7 原理图放置完成2.8 编写程序&#xff0c;进行仿真2.9 仿真 三、常用元器件图示和功能介绍3.1 元件…

【回眸】Tessy 单元测试软件使用指南(四)常见报错及解决方案与批量初始化的经验

前言 分析时Tessy的报错 1.fatal error: Tricore/Compilers/Compilers.h: No such file or directory 2.error: #error "Compiler unsupported" 3.warning: invalid suffix on literal;C11 requires a space between literal and string macro 4.error: unknown…

螺蛳壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习01(环境准备)

1 准备工作 由于创建数据中心需要安装很多服务器&#xff0c;这些服务器要耗费很所物理物理计算资源、存储资源、网络资源和软件资源&#xff0c;作为穷学生只有几百块的n手笔记本&#xff0c;不可能买十几台服务器来搭建数据中心&#xff0c;也不愿意跑实验室&#xff0c;想躺…

第十二章--- fixed 和 setprecision 函数、round 函数、进制转换及底层逻辑

1. 保留几位小数 在C中&#xff0c;如果你想要控制输出的小数点后的位数&#xff0c;可以使用<iomanip>头文件提供的fixed和setprecision函数。这里的fixed用于设置浮点数的输出格式为定点表示法&#xff0c;而setprecision(n)则用来指定小数点后保留的位数。具体用法如…