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

封装axios的两种方式

作为前端工程师,经常需要对axios进行封装以满足复用的目的。在不同的前端项目中使用相同的axios封装有利于保持一致性,有利于数据之间的传递和处理。本文提供两种对axios进行封装的思路。

1. 将请求方式作为调用参数传递进来

  1. 首先导入了axios, AxiosInstance和AxiosResponse模块,用于创建一个http请求的实例和处理响应结果。
  2. 定义了一个getBaseUrl函数,用于获取请求的基础URL。
  3. 创建了httpProto实例,使用axios.create方法进行创建。并配置了请求的超时时间为5000ms,不携带凭证,设置请求的Content-Type为application/json;charset=UTF-8,并允许跨域访问。
  4. 添加了一个请求拦截器,通过httpProto.interceptors.request.use方法,对请求进行处理。首先使用getBaseUrl函数获取基础URL,并将其添加到请求的baseURL属性中。然后通过getToken函数获取凭证,如果凭证存在,则将其添加到请求的Authorization头部字段中。最后返回处理后的请求配置。
  5. 添加了一个响应拦截器,通过httpProto.interceptors.response.use方法,对响应进行处理。首先获取响应的data字段,然后判断data.result的值,如果为0则表示请求成功,直接返回data。否则将返回一个失败的Promise,reject的值为data。
  6. 定义了一个http函数,用于发送请求。这个函数接收一个method参数和其他参数(rest),然后通过httpProto[method](...rest)的形式调用httpProto实例的对应方法发送请求。
  7. 定义了一个urls对象,用于存储可供使用的URL路径,其中有一个示例路径example。
  8. 定义了一个methods对象,用于存储常用的请求方法名称,包括get、post和delete

完整的代码如下所示:

import axios, { AxiosInstance, AxiosResponse } from "axios";
import { getToken } from "./token";// 获取请求的基础URL
const getBaseUrl = () => `http://${window.constant.serverIp}:8888}`;// 创建http请求的实例对象
const httpProto: AxiosInstance = axios.create({timeout: 5000,withCredentials: false,headers: {'Content-Type': 'application/json;charset=UTF-8','Access-Control-Allow-Origin': '*',}
});// 添加请求拦截器
httpProto.interceptors.request.use((config: any) => {// 配置baseURLconfig.baseURL = getBaseUrl();// 获取凭证const token = getToken();if (token) {// 如果有凭证就加上此凭证config.headers.Authorization = `${token}`;}return config;
}, (error) => {return Promise.reject(error)
});// 添加响应拦截器
httpProto.interceptors.response.use((response: AxiosResponse) => {const { data } = response// 统一处理响应结果if (data.result === 0) {return data;} else {return Promise.reject(data);}},(error) => {// 统一处理错误信息return Promise.reject(error);}
);// 将httpProto实例,也就是AxiosInstance实例对象封装起来
const http = (method: string, ...rest: any) => {return httpProto[method](...rest);
}// 可供使用的urls
const urls = {example: `/prod/example`,
}const methods = {get: 'get',post: 'post',delete: 'delete',
}export { http, urls, methods };

2. 直接调用某请求方式对应的请求方法

  1. 导入了axios模块的相关类型和函数。
  2. 定义了printLog函数,用于处理日志输出
  3. 定义了IResponse接口,表示请求响应对象的格式。
  4. 定义了RequestParams接口,表示发送请求的配置项的格式。
  5. 定义了IHttp接口,表示封装对象支持的请求方式/方法。
  6. 定义了req对象,用于向外暴露支持的请求方法。
  7. 定义了methods数组,表示支持的请求方式类型。
  8. 使用forEach方法遍历methods数组,逐步构造req对象上的各个方法
  9. 在每个方法的构造过程中,进行以下步骤:
    • 参数合并,将默认的responseType设置为'json'。
    • 从params对象中解构需要的参数。
    • 使用axios.create方法创建一个AxiosInstance实例对象。
    • 创建请求头对象,并设置一些常用的请求头信息。
    • 构造请求配置对象AxiosRequestConfig
    • 根据请求方式对请求配置进行修正,主要是将data赋值到相应的字段中。
    • 添加请求拦截器,并在成功和失败的情况下返回配置。
    • 添加响应拦截器,并在成功和失败的情况下返回处理结果。
    • 构造请求成功的回调函数,对返回数据进行格式化的操作。
    • 构造请求失败的回调函数,处理错误日志和断网情况。
    • 发送请求并将请求结果作为函数的返回值。
  10. 默认导出req对象。

以下是加上注释的完整代码:

import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';// 日志处理,可定制
const printLog = console;// 作为被Promise包裹的请求响应对象的格式
export interface IResponse {code: number;msg: string;result: {lastOperaTime: number;data: any;};
}// 发送请求的配置项的格式
export interface RequestParams {url: string;baseUrl?: string;data?: object;filter?: boolean;responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream';headers?: any;timeout?: number;
}// 封装对象支持的请求方式/方法
interface IHttp {get?: (params: RequestParams) => Promise<any>;post?: (params: RequestParams) => Promise<any>;put?: (params: RequestParams) => Promise<any>;patch?: (params: RequestParams) => Promise<any>;delete?: (params: RequestParams) => Promise<any>;
}// 支持的请求方式类型
export type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';// 向外暴露出去的对象
const req: IHttp = {};// 支持的请求类型
const methods: HttpMethod[] = ['get', 'post', 'put', 'patch', 'delete'];// 遍历methods数组,逐步构造req对象
methods.forEach((_m: HttpMethod) => {// 使用遍历的方式对req对象上的各个方法进行构造req[_m] = (params: RequestParams) => {// 1. 构造参数合并params = {...params,responseType: params.responseType || 'json',};// 2. 从使用对象方法的形参上结构出必要的参数const {url, // 服务器地址data, // 有效载荷filter = true, // 过滤器responseType, // 返回类型timeout, // 超时时间} = params;// 3. 使用axios创建AxiosInstance实例对象const instance = axios.create({baseURL: params.baseUrl ?? `http://${window.location.hostname}`,timeout,});// 4. 创建请求头对象const headers = {lastOperaTime: Date.now(), // 时间戳token: getToken(), // 凭证lang: getLocalLocale(), // 语言Accept: 'application/json', // 接受返回数据的类型'Content-Type': 'application/json; charset=utf-8', // 内容格式};// 5. 请求配置const axiosConfig: AxiosRequestConfig = {method: _m, // 请求方法url, // 服务器地址headers: {// 合并请求头...headers,...(params.headers || {}),},responseType, // 返回值类型};// 6. 针对不同的请求类型需要对请求配置进行修正if (data) {// 对于有效载荷,不同的请求方式携带信息的方式是不同的,在这里做了区分if (_m === 'get') {axiosConfig.params = data;} else if (data instanceof FormData) {axiosConfig.data = data;} else {axiosConfig.data = data;}}// 添加请求拦截器instance.interceptors.request.use(// 占位(config: any) => {return config;},// 失败则返回失败(error: any) => {return Promise.reject(error);});// 7. 添加响应拦截器instance.interceptors.response.use(// 成功的回调,将发起请求的参数作为第二参数回传(res: any) => handleSuccess(res, params),// 失败的回调,将发起请求的参数作为第二参数回传(err: any) => handleError(err, params));// 8. 构造请求成功的回调函数 -- 主要是对返回数据进行格式化的操作function handleSuccess(response: AxiosResponse<IResponse>, requestParams: RequestParams) {if (response.data) {// 解构数据const { code, msg, result } = response.data;if (code !== 0) {printLog.error(msg);}return filter ? result?.data ?? result : response.data;} else {printLog.error('incorrect data format');return response.data;}}// 9. 构造请求失败的回调函数function handleError(err: AxiosError, requestParams: RequestParams) {if (err.response) {printLog.error(`api: ${requestParams.url}: ${err.response.status}`);}if (err instanceof Error) {if (err.message) {printLog.error(err.message);}}if (!window.navigator.onLine) {// 处理断网情况printLog.error('netwrok error');}return Promise.reject(err);}// 10. 发送请求并将请求结果(Promise对象)作为函数的返回值return instance.request(axiosConfig);};
});export default req;

 给大家推荐一个实用面试题库

1、前端面试题库 (面试必备)            推荐:★★★★★

地址:web前端面试题库

 

相关文章:

封装axios的两种方式

作为前端工程师&#xff0c;经常需要对axios进行封装以满足复用的目的。在不同的前端项目中使用相同的axios封装有利于保持一致性&#xff0c;有利于数据之间的传递和处理。本文提供两种对axios进行封装的思路。 1. 将请求方式作为调用参数传递进来 首先导入了axios, AxiosIn…...

【自然语言处理】NLTK库的概念和作用

文章目录 一、NLTK库介绍二、NLTK库的使用2.1 初级使用2.2 中级使用 参考资料 一、NLTK库介绍 Natural Language Toolkit (NLTK)是一个广泛使用的Python自然语言处理工具库&#xff0c;由Steven Bird、Edward Loper和Ewan Klein于2001年发起开发。NLTK的目的是为自然语言处理&…...

Python爬虫如何解决提交参数js加密

注意&#xff01;&#xff01;&#xff01;&#xff01; 仅做知识储备莫拿去违法乱纪&#xff0c;有问题指出来&#xff0c;纯做笔记记录 由于&#xffe5;%…………&&%#%** 所以&#xff01;#&#xffe5;……&*……* 啥也不说直接上代码 import execjs js_ji…...

云数据库及RDS数据库介绍

1.云数据库概念 云数据库是指被优化或部署到一个虚拟计算环境中的数据库&#xff0c;具有按需付费、按需扩展、高可用性以及存储整合等能力。 2.云数据库特性 云数据库的特性有&#xff1a;实例创建快速、支持只读实例、读写分离、故障自动切换、数据备份、Binlog备份、SQL审…...

c语言进阶部分详解(详细解析自定义类型——枚举,联合(共用体))

上篇文章介绍了结构体相关的内容&#xff0c;大家可以点击链接进行浏览&#xff1a;c语言进阶部分详解&#xff08;详细解析自定义类型——结构体&#xff0c;内存对齐&#xff0c;位段&#xff09;-CSDN博客 各种源码大家可以去我的gitee主页进行查找&#xff1a;唔姆 (Nerow…...

使用 Requests 库和 PHP 的下载

以下是一个使用 Requests 库和 PHP 的下载器程序&#xff0c;用于从 www.people.com.cn 下载音频。此程序使用了 https://www.duoip.cn/get_proxy 这段代码。 import requests from bs4 import BeautifulSoup import pafy import timedef get_proxy():url "https://www.…...

ConcurrentHashMap底层具体实现知道吗?实现原理是什么

从这三个方面来回答&#xff1a; ConcurrentHashMap 的整体架构 ConcurrentHashMap 的基本功能 ConcurrentHashMap 在性能方面的优化 ConcurrentHashMap 的整体架构 这个是 ConcurrentHashMap 在 JDK1.8 中的存储结构&#xff0c;它是由数组、单向链表、红黑树组成. 当我们初始…...

Go语言“Go语言:掌握未来编程的利器“

Go语音的发展史可以追溯到2009年&#xff0c;当时谷歌公司推出了一款名为“Google Assistant”的智能助手&#xff0c;它使用自然语言处理技术来与用户进行交互。随后&#xff0c;Go语音逐渐发展成为一种广泛使用的语音技术&#xff0c;其发展历程如下&#xff1a; 起步阶段&a…...

达梦管理工具报错“结果集不可更新,请确认查询列是否出自同一张表,并且包含值唯一的列。”

在使用达梦数据库管理工具时&#xff0c;我们测试过程中时常需要更新表数据&#xff0c;有时为了便捷&#xff0c;会直接使用管理工具修改表数据的值&#xff0c;但偶尔会遇到“结果集不可更新&#xff0c;请确认查询列是否出自同一张表&#xff0c;并且包含值唯一的列。”的报…...

TensorFlow2从磁盘读取图片数据集的示例(tf.keras.utils.image_dataset_from_directory)

import os import warnings warnings.filterwarnings("ignore") import tensorflow as tf from tensorflow.keras.optimizers import Adam from tensorflow.keras.applications.resnet import ResNet50#数据所在文件夹 base_dir ./data/cats_and_dogs train_dir os…...

Unity开发过程中的一些小知识点

1、如何查询挂载了指定脚本的游戏物体 可以直接在Hierarchy面板上&#xff0c;搜索想要找的脚本名 2、如何将Unity生成的多个相同游戏物体获得序号 可以使用Unity的API Transform.GetSiblingIndex() 实现。 Transform.GetSiblingIndex()gameobject.idTransform.GetSiblingI…...

大语言模型(LLM)综述(一):大语言模型介绍

A Survey of Large Language Models 前言1. INTRODUCTION2. OVERVIEW2.1 大语言模型的背景2.2 GPT系列模型的技术演变 前言 随着人工智能和机器学习领域的迅速发展&#xff0c;语言模型已经从简单的词袋模型&#xff08;Bag-of-Words&#xff09;和N-gram模型演变为更为复杂和…...

在Ubuntu上安装和挂载NFS

在Ubuntu上安装和挂载NFS可以按照以下步骤进行&#xff1a; 安装NFS客户端工具&#xff1a;在Ubuntu上&#xff0c;可以使用以下命令安装NFS客户端工具&#xff1a; shell复制代码 sudo apt-get install nfs-common 创建挂载点&#xff1a;在本地Ubuntu计算机上&#xff0c;…...

Python 实现的简易数据库管理系统 (DBMS)

在这篇文章中&#xff0c;我们将深入探讨如何使用 Python 从头开始实现一个简易的数据库管理系统 (DBMS)。这不是一个生产级的 DBMS&#xff0c;但它为我们提供了一个如何构建数据库系统的基础概念。 1. 数据表的实现 首先&#xff0c;我们定义了一个 Table 类来模拟数据库中…...

1.初识MySQL

初识 MySQL 1.服务器处理客户端请求2.常用存储引擎3.关于存储引擎的一些操作3.1 查看当前服务器程序支持的存储引擎3.2 设置表的存储引擎3.2.1 创建表时指定存储引擎3.2.2 修改表的存储引擎 4.总结 MySQL 默认采用 TCP/IP 的方式来处理客户端与服务器连接过程。 1.服务器处理客…...

【列存储学习总结】

在 OpenGauss 中&#xff0c;列存储是一种高效的数据存储方式&#xff0c;它在处理分析查询和数据仓库工作负载时具有很高的性能优势。列存储将表中的数据按列存储在磁盘上&#xff0c;而不是按行存储&#xff0c;这样可以极大地提高数据读取和分析操作的效率。当涉及大量数据的…...

小记java正则表达式中matcher.find() 和 matcher.matches() 的区别

matcher.find() 顾名思义&#xff0c;find为查找&#xff0c;其功能为查找字符串中是否有符合条件的字串&#xff08;包含本身&#xff09;&#xff0c;当查找到时即返回true&#xff0c;更多地与matcher.group(int i) 配合使用&#xff0c;用于从字符串中取出特定字串。 mat…...

当中国走进全球化的“深水区”,亚马逊云科技解码云时代的中国式跃升

中国跨境贸易中支付金融与服务领域的综合创新型企业连连国际的联席CEO沈恩光发现&#xff0c;眼下&#xff0c;很多跨境电商的出海方式已发生了变化。几年前&#xff0c;它们还主要借助第三方电商平台&#xff0c;而现在&#xff0c;更多公司开始选择通过自主渠道进入海外市场&…...

零基础Linux_21(多线程)页表详解+轻量级进程+pthread_create

目录 1. 页表详解 1.1 权限条目页框 1.2 页目录页表项 2. 线程的概念 2.1 轻量级进程 2.2 Linux的线程 2.3 pthread_create 2.4 原生线程库LWP和PID 3. 线程的公有资源和私有资源 3.1 线程的公有资源 3.2 线程的私有资源 4. 线程的优缺点 4.1 线程的优点 4.2 线程…...

nodejs+wasm+rust debug及性能分析

文章目录 背景v8引擎自带的profilelinux的perf采集wasm三方库性能分析编译debug版本wasmrust程序debug调试异常模型正常模型结论优化 参考 Node使用火焰图优化CPU爆涨 - 掘金 【Node.js丨主题周】理解perf 与火焰图-腾讯云开发者社区-腾讯云 Easy profiling for Node.js Applic…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

nnUNet V2修改网络——暴力替换网络为UNet++

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...

C++_哈希表

本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、基础概念 1. 哈希核心思想&#xff1a; 哈希函数的作用&#xff1a;通过此函数建立一个Key与存储位置之间的映射关系。理想目标&#xff1a;实现…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”

非常好&#xff0c;我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题&#xff0c;统一使用 二重复合函数&#xff1a; z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y))​ 来全面说明。我们会展示其全微分形式&#xff08;偏导…...