🔗 sluggard-http | 基于 axios 的多功能请求库,助你玩转请求

✨ 请确保已安装 axios

✨ 项目npm地址 www.npmjs.com/package/slu...

sluggard-http - 官方文档地址

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' })

更多请参考 快速开始 | sluggard-http (wem3.cn)

内置功能

自定义请求别名

简单的说就是可以自定义除 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() 即可调用
TS 复制代码
http.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)
}

请求控制

提供多种对 进行中 请求进行控制的方法,包括 请求更新全局请求清除请求拦截

请求更新

  • 在当前请求处于 进行中 时, 若发起 相同 请求, 则会触发请求更新,取消 之前未完成的请求, 避免重复请求

    • 例如连续发起两 相同 个请求
    TS 复制代码
    const 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 模式下,q1q2 被视为同一请求,q3 被视为不同请求
path 模式下,q1q2q3 都被视为同一请求
free 模式下,q1q2q3 都被视为不同请求

  • 使用方法
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" }); 

全局请求清除

  • 清除并 取消 当前所有的请求, 往往在 路由变化 时使用,避免请求资源的浪费
    • 当用户进行页面切换时,若之前页面存在还 未完成 的请求, 可将其清除,以节省请求资源
    • sluggard-http 提供 clearPending() 方法,用于清除当前还未完成的所有请求
TS 复制代码
// 以 vueRouter 为例,在路由守卫中进行配置
router.afterEach(() => {
  http.clearPending(); // 清除所有还未完成的请求
});

请求拦截

  • 对还在 进行中指定 请求进行拦截, 并 取消 请求

    • sluggard-http 提供 abortPending() 方法,用于根据指定条件来拦截请求
  • 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 等进度条插件配合使用
相关推荐
Asort12 分钟前
JavaScript 从零开始(六):控制流语句详解——让代码拥有决策与重复能力
前端·javascript
无双_Joney31 分钟前
[更新迭代 - 1] Nestjs 在24年底更新了啥?(功能篇)
前端·后端·nestjs
在云端易逍遥33 分钟前
前端必学的 CSS Grid 布局体系
前端·css
ccnocare34 分钟前
选择文件夹路径
前端
艾小码34 分钟前
还在被超长列表卡到崩溃?3招搞定虚拟滚动,性能直接起飞!
前端·javascript·react.js
闰五月35 分钟前
JavaScript作用域与作用域链详解
前端·面试
泉城老铁39 分钟前
idea 优化卡顿
前端·后端·敏捷开发
前端康师傅39 分钟前
JavaScript 作用域常见问题及解决方案
前端·javascript
司宸40 分钟前
Prompt结构化输出:从入门到精通的系统指南
前端