✨ 请确保已安装 axios
✨ 项目npm地址 www.npmjs.com/package/slu...
sluggard-http 基于 axios 的多功能请求库
与 axios 使用方式完全兼容,并提供
自定义请求别名
功能与多种请求控制
方法。且具有完善的 typescript 支持
前言
前端开发兜兜转转总是绕不开 axios
相关的封装,在各种项目中也解决了很多请求相关的痛点问题,于是决定将已有的积累做下封装,也方便后期的使用。
快速开始
sluggard-http
的使用基本与Axios Instance
一致,内部使用单例模式下的axios实例进行请求。
- 使用
Http.create()
( 与axios.create()
基本相同 ) 来创建实例 - 用法可参考 axios 文档 The Axios Instance
Http.create()
的第一个参数与axios.create()
的config
参数一致, 第二个参数为 sluggard-http自定义请求别名
和进度生命周期
功能的配置项,可按需配置。
TS
import { Http } from 'sluggard-http'
import type { RequestConfig, LifeType } from 'sluggard-http'
const methodAlias = {
// 自定义请求别名配置
download: {
axiosMethod: 'post',
handle: (url: string, data: any, config: RequestConfig) => {
return [url, data, { ...config, responseType: 'blob' }]
},
},
} as const
const life: LifeType = {
// 进度生命周期配置
begin: () => {
NProgress.start()
},
end: () => {
NProgress.done()
},
}
export const http = Http.create<typeof methodAlias>(
{
baseURL: '...',
timeout: 1000,
headers: {'Authorization': '...'}
},
{
methodAlias,
life
}
)
使用实例发起请求
- 与
Axios Instance
一致
TS
import http from "..." // 引入创建好的实例
http.get('/user?ID=12345')
http.post('/user', { firstName: 'Fred', lastName: 'Flintstone' })
内置功能
自定义请求别名
简单的说就是可以自定义除
GET
/POST
/PUT
/DELETE
... 等别名以外的其他请求别名,且支持在调用自定义请求别名时对请求体
/响应体
进行统一处理
- 举个例子
- 通常发起一个下载文件请求时, 都需要在请求体中添加
responseType: 'blob'
此时可以创建一个download
别名, 调用此别名时发起post
请求
并自动携带responseType: 'blob'
参数
TS
import type { RequestConfig } from 'sluggard-http'
import { Http } from 'sluggard-http'
const methodAlias = {
// 👇 要新建的别名名称
download: {
// 此别名实际上调用的 axios 方法
axiosMethod: 'post',
// 别名处理函数
handle: (url: string, data: any, config: RequestConfig) => {
// 为请求体添加 responseType 参数
return [url, data, { ...config, responseType: 'blob' }]
},
},
} as const // 此处获取字面量类型,有助于ts类型推导
// 创建 http 实例 传入 typeof methodAlias 泛型,使 http.download() 能够自行推导类型
export const http = Http.create<typeof methodAlias>(
{
baseURL: '...',
timeout: 1000,
headers: {'Authorization': '...'}
},
{
methodAlias, // 此处引入配置
life: { ... },
}
)
效果
- 配置将新增一个
download
别名并挂载到http
实例上- 通过
http.download()
即可调用
TShttp.download('/downloadTable', { ids: ['1', '2', '3'] })
调用时等于执行了以下
伪代码
TS// 伪代码 👇 http.download(url, data, config){ // 调用你定义的别名处理函数, 为请求体添加 responseType 参数 const [url, data, config] = handle(url, data, config) // 返回实际调用的 axios 方法 return http.post(url, data, config) }
- 👆 上述
download
别名实际上是一个修改请求体的别名
(在RequestConfig
中添加了参数) - 自定义请求别名除了可以统一修改请求体外,也可配合
拦截器
统一修改响应体,甚至可以配置GET
/POST
/PUT
/DELETE
... 等别名,来对这些已有别名进行重构。具体可查看文档。
请求控制
提供多种对
进行中
请求进行控制的方法,包括请求更新
、全局请求清除
、请求拦截
请求更新
-
在当前请求处于
进行中
时, 若发起相同
请求, 则会触发请求更新,取消
之前未完成的请求, 避免重复请求- 例如连续发起两
相同
个请求
TSconst get1 = http.get('/user?ID=12345') setTimeout(()=>{ const get2 = http.get('/user?ID=12345') },200)
- 若
get1
在200ms内未请求完成,get2
发起请求时,get1
将被取消
- 例如连续发起两
-
且
相同
的判断标准分为3个等级,默认为all
(无需配置)字面量 级别名称 释义 all
(默认值)全量 请求方式
&请求地址
&query
&data
都相同时,视为相同请求
path
路径 请求方式
&请求地址
相同时,视为相同请求
free
自由 每次请求都被视为 不同请求
,不受请求更新控制,常用于统计计数类接口 -
示例
TS
const q1 = http.post('/user', { firstName: 'Fred', lastName: 'Flintstone' })
const q2 = http.post('/user', { firstName: 'Fred', lastName: 'Flintstone' })
const q3 = http.post('/user', { firstName: 'George', lastName: 'Bush' })
all
模式下,q1
和q2
被视为同一请求,q3
被视为不同请求
path
模式下,q1
、q2
、q3
都被视为同一请求
free
模式下,q1
、q2
、q3
都被视为不同请求
- 使用方法
TS
// 无需配置 默认为 all 级别 👇
const httpRes = await http.post("/getList", data);
// 配置为 path 级别 👇
const httpRes = await http.post("/getList", data, { updateLevel: "path" });
// 配置为 free 级别 👇
const httpRes = await http.post("/getList", data, { updateLevel: "free" });
path
级别的使用场景可查看文档。
全局请求清除
- 清除并
取消
当前所有的请求, 往往在路由变化
时使用,避免请求资源的浪费- 当用户进行页面切换时,若之前页面存在还
未完成
的请求, 可将其清除,以节省请求资源 - sluggard-http 提供
clearPending()
方法,用于清除当前还未完成的所有请求
- 当用户进行页面切换时,若之前页面存在还
TS
// 以 vueRouter 为例,在路由守卫中进行配置
router.afterEach(() => {
http.clearPending(); // 清除所有还未完成的请求
});
- 如果某些请求需要设置不被清除,可在请求中单独配置,具体可查看文档。
请求拦截
-
对还在
进行中
的指定
请求进行拦截, 并取消
请求- sluggard-http 提供
abortPending()
方法,用于根据指定条件来拦截请求
- sluggard-http 提供
-
abortPending
接收的参数有两种类型,一种是字符串类型的拦截标识符
,另一种是数组类型的请求标识数组
-
拦截标识符
来自请求返回的Promise
对象,sluggard-http 对 axios 的响应Promise对象
进行了重构,在其上添加了一个abortSignUuidCode
值用于请求拦截- 使用方法
TS// 从请求 HttpPromise 对象中获取拦截标识符 abortSignUuidCode const { abortSignUuidCode } = http .post("/getList", { size: 10, current: 1 }) // 通过 abortSignUuidCode 拦截请求 http.abortPending(abortSignUuidCode)
- 由于
abortSignUuidCode
经由 Promise 对象中获取,所以无法在async/await
中使用
-
请求标识数组
适用于拦截与请求不在同一域的情况,此时无法方便的获取到abortSignUuidCode
- 使用方法
TS// 发起请求 http .post("/getList", { size: 10, current: 1 }) // 通过 [请求方式, 请求地址, 请求参数] 组成的请求标识数组来拦截请求 http.abortPending(["post", "/getList", { size: 10, current: 1 }]);
-
-
具体可查看文档
进度生命周期
sluggard-http 支持在
单个请求开始
/全部请求结束
时抛出钩子函数
- 常与
NProgress
等进度条插件配合使用
- 具体可查看文档