封装axios二方包

前言

在前端项目开发中,直接使用 axios 发起网络请求虽然简单高效,但在大型项目或多项目协作中存在维护性差、重复代码多等问题。因此,二次封装axios的二方包是有必要的

功能需求

1. 统一请求配置

通过封装可以设置全局默认配置(如超时时间、基础路径、请求头等),避免每个项目都手动重复设置。

2. 拦截器统一管理

封装后可以集中管理请求和响应拦截器,实现通用逻辑(如错误统一处理等)

3. 接口返回格式标准化

封装可统一处理响应数据结构,确保所有接口返回的数据格式一致,便于业务层消费

4. 支持多个项目的复用

将封装后的工具打包插件,可在多个项目中复用,减少重复开发工作。

5. 增强可维护性和扩展性

当需要升级功能或者变更统一逻辑时,只需修改封装层,无需改动业务代码,降低耦合度。

6. 统一错误处理机制

可在封装中统一处理网络异常、业务错误码(如 401、500),并提供友好提示或自动重试机制。

7. 提升开发体验

封装后对外暴露简洁的 API,如 get, post 方法,让开发者更专注于业务逻辑而非底层请求细节。

功能设计

1.类接口设计

封装一个接口类,包含一个构造函数constructor(options: RequestClientOptions = {})

初始化Axios实例时可以传入一些配置参数,比如timeout超时时间、baseUrl,或是拦截器等

2.主要成员变量
instance AxiosInstance Axios实例
addRequestInterceptor Function 自定义添加的请求拦截
addResponseInterceptor Function 自定义添加的相应拦截
requestConfig 记录config配置
download Function 通过一个单独的类生成文件下载方法
upload Function 通过一个单独的类生成文件上传方法
loading boolean 记录是否需要展示loading加载状态
3.默认的全局配置

在constructor中有个defaultConfig以便不用过多配置,如下

js 复制代码
class RequestClient {
    constructor(options: RequestClientOptions = {}) {
        const defaultConfig: RequestClientOptions = {
          headers: {
            'Content-Type': 'application/json;charset=utf-8',
          },
          responseReturn: 'raw',
          // 默认超时时间
          timeout: 10000,
        };
    }
}
4.请求参数处理

初始化对axios的配置参数paramsSerializer做处理,支持自定义参数序列化方式,也可以使用默认值

5.默认的全局拦截

在内部会定义默认的全局请求拦截和响应拦截,譬如处理请求时的页面加载loading,处理通用场景下异常status:403,500等状态码异常错误提示等(支持配置)

6.通用请求工具函数

封装通用请求工具函数request,并支持自定义或默认响应泛型供用户消费,并根据request进一步封装get,post,delete,put/patch供使用

js 复制代码
type ResponseType<T = any> = {
    data: T
    code: number
    message: string
}
type RequestMethods = Extract<
  Method,
  'get' | 'post' | 'put' | 'delete' | 'patch' | 'option' | 'head'
>

public async request<T = ResponseType>(
    method: RequestMethods
    url: string,
    config: RequestClientConfig,
): Promise<AxiosResponse<T>> {
...
}
7.取消请求

部分场景下存在接口需主动取消请求,如tab切换过程中存在接口未响应的,在切换后不需要请求时取消请求,避免存在接口排队的情况

类设计图

classDiagram class RequestClient { +_instance: AxiosInstance +_clientConfig: RequestClientOptions +_interceptorsConfig: InterceptorsConfig +addRequestInterceptor: Function +addResponseInterceptor: Function +upload: Function +download: Function +downloadByPost: Function +downloadByBlob: Function +downloadByBlobPost: Function +requestControllers: Map +request(method, url, config?: RequestClientConfig): Promise +get(url, config?: RequestClientConfig): Promise +post(url, data?, config?: RequestClientConfig): Promise +put(url, data?, config?: RequestClientConfig): Promise +patch(url, data?, config?: RequestClientConfig): Promise +delete(url, param?, config?: RequestClientConfig): Promise +initSuccessCodes(successCodes: number | number[] | undefined | null): Array +initRequestInterceptor(): void +initResponseInterceptor(): void +addRequestController(key): void +removeRequestController(key): void +cancelRequest(key, message?): void +cancelAllRequests(message?): void } class FileDownloader { +client: RequestClient +notification: NotificationConfig +message: MessageConfig +download(url, config): Promise +downloadByPost(url, data, config): Promise +downloadByBlob(url, config): Promise +downloadByBlobPost(url, data, config): Promise } class FileUploader { +client: RequestClient +upload(url, data, config)?: Promise } class Interceptormanager { +instance: AxiosInstance +addRequestInterceptor() RequestInterceptorConfig +addResponseInterceptor() ResponseInterceptorConfig } RequestClient --> FileDownloader : 依赖 RequestClient --> FileUploader : 依赖 RequestClient --> Interceptormanager : 依赖
使用设计
  1. 实例初始化
js 复制代码
// 使用默认
const  http = new RequestClient()
// 添加配置项
const  http = new RequestClient(
    config: RequestClientOptions
)

2.自定义config配置

首先config的类型是RequestClientOptions,他继承自AxiosRequestConfig,并在其基础上增加了一些其他的配置属性,譬如paramsSerializer指定序列化,interceptors初始化时指定业务的自定义拦截器等

或是初始化完成之后通过调用实例中的addRequestIntercepter或addResponseIntercepter去给axios实例的interceptors添加拦截器处理

  1. 业务代码使用
csharp 复制代码
// api接口,如module=user
const http = new RequestClient()
// 1. 直接使用request方法
const _userInfo = (params) => {
    return  http.request<ResponseType>('get', url, {params})
}
// 2.使用具体的方法
const _userInfo = (params) => {
    return  http.get<ResponseType>( url, {params})
}

这里的DataType是接口返回的data中数据类型,方便提示

调用流程图
相关推荐
PythonFun5 分钟前
WPS中表格行高无法手动调整怎么办?
前端·html·wps
IT_陈寒11 分钟前
JavaScript性能优化:7个V8引擎内部原理帮你减少90%内存泄漏的实战技巧
前端·人工智能·后端
narukeu21 分钟前
聊下 rewriteRelativeImportExtensions 这个 TypeScript 配置项
前端·javascript·typescript
爬山算法22 分钟前
Netty(22)如何实现基于Netty的HTTP客户端和服务器?
服务器·网络协议·http
开压路机22 分钟前
模拟实现反向迭代器
前端·c++
爱吃香蕉的阿豪23 分钟前
NET Core中ConcurrentDictionary详解:并发场景下的安全利器及服务端实践
安全·http·.netcore·高并发
San30.24 分钟前
从 0 到 1 打造 AI 冰球运动员:Coze 工作流与 Vue3 的深度实战
前端·vue.js·人工智能
xiangzhihong827 分钟前
Visual Studio 2026 正式发布,带来 AI 原生 IDE 和提升性能
前端
安_29 分钟前
为什么 Vue 要用 npm run dev 启动
前端·vue.js·npm
LYFlied29 分钟前
【每日算法】LeetCode 437. 路径总和 III
前端·算法·leetcode·面试·职场和发展