✨ 请确保已安装 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等进度条插件配合使用
- 具体可查看文档