npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@seayoo-web/request

v3.4.5

Published

request tools for seayoo web

Downloads

527

Readme

网络请求工具库

为什么

市面上流行的网络请求工具有以下一些限制或不足:

  1. 体积过大
  2. 流行的几个 request 工具均不默认支持重试配置
  3. 对响应结果不进行更多检查(无类型守卫,无结构分析),无法完美对接 ts 代码
  4. 功能过于冗余,而相当多特性实际开发中使用不到

特性

  1. 默认基于 fetch,请求和响应解析均默认基于 json 或 text
  2. 支持重试配置 maxRetry / retryResolve / retryInterval
  3. 支持响应结果处理策略 responseRule 和通用提示配置
  4. 支持类型守卫 typeGuard
  5. 支持多实例,多端(浏览器,nodejs,微信小程序)
  6. get 请求函数支持并发缓存(默认缓存 500ms)
  7. 函数永不抛错,返回固定解析结构 { ok, data, status, headers, code, message }
  8. 提供格式化良好的 sentry 信息用于错误上报
  9. 提供 jsonp / jsonx 函数,支持带上传进度的 upload 函数

示例

import { get } from "@seayoo-web/request"

interface IUser {
    name: string,
    id:   string
}

function isUserList(data: unknown): data is IUser[] {
    return Array.isArray(data)
    	&& data.every(item => !!item && typeof item === "object" && "name" in item && "id" in item)
}

export async function getUserList(): Promise<IUser[]> {
    const { data } = await get("/api/user", isUserList)
    return data || []
}

配置响应规则

// 浏览器环境
import { setGlobalConfig } from "@seayoo-web/request";
// nodejs 环境
import { setGlobalConfig } from "@seayoo-web/request/node";
// 或在某些编译配置或编辑器中无法识别上述路径,可以改用实际的 dist 路径导入
import { setGlobalConfig } from "@seayoo-web/request/dist/node";

// 以下是默认的全局配置(更多介绍请参考下方全局配置)
setGlobalConfig({
  // api 基础路径,默认根目录
  baseURL: "/",
  // 响应解析规则
  responseRule: {
    // status 成功时解析策略:将 body 作为响应数据
    ok: { resolve: "body" },
    // status 失败时解析策略:将响应体解析为 json 并读取 message 字段作为错误消息
    failed: { resolve: "json", messageField: "message" },
  },
  // 更多全局配置参考下方介绍
});

全局函数和自定义实例

// 以下为浏览器环境全局默认导出的工具函数
import { get, post, put, patch, del, head } from "@seayoo-web/request";
// 以下是 nodejs 环境全局默认导出的工具函数
import { get, post, put, patch, del, head } from "@seayoo-web/request/node";
// 以下是 微信小程序 环境全局默认导出的工具函数
// 注意,微信不支持 patch 方法
import { get, post, put, del, head } from "@seayoo-web/request/wx";

// 浏览器环境自定义创建实例
import { NetRequest } from "@seayoo-web/request";
const { get, post, put, patch, del, head, setConfig } = NetRequest();

// nodejs环境自定义创建实例
import { NetRequest } from "@seayoo-web/request/node";
const { get, post, put, patch, del, head, setConfig } = NetRequest();

// 微信小程序自定义创建实例
import { NetRequest } from "@seayoo-web/request/wx";
const { get, post, put, del, head, setConfig } = NetRequest();

全局配置参数

import { setGlobalConfig } from "@seayoo-web/request";
// 全局配置字段说明见下,所有字段均可选
// 全局配置仅仅影响全局导出函数,比如直接导出的 get, post 等,对于自定义实例没有影响
setGlobalConfig({ baseURL: "/api" });

// 自定义实例和全局配置是独立的
import { NetRequest } from "@seayoo-web/request";
// 可以创建时传递
const { get, post, setConfig } = NetRequest({ baseURL: "/api" });
// 也可以随时修改
setConfig({ timeout: 10000 });

baseURL

类型:string

说明:需要以 / 开头或者是一个完整的 url 地址;此设置会给所有请求的 url 增加 baseURL 作为前缀,但以下情况除外

  1. 请求时传入的 url 为完整 url,即以 http:// 或 https:// 开头

node 环境仅仅支持完整 url 地址作为 baseURL

credentials

类型:"omit" | "same-origin" | "include"

说明:是否携带用户认证信息(cookie, basic http auth 等),默认 "same-origin",当需要跨域发送 cookie 时可以设置为 include;当需要明确忽略 cookie(比如认证信息已经放入自定义 header 头)时,可以设置为 omit;

仅浏览器环境有效;如果运行环境不支持 fetch 则 omit 无效;

timeout

类型:number

说明:请求超时设置,单位 ms,默认 10000,即 10 秒

cacheTTL

类型:number

说明:用于控制全局请求的缓冲时长,单位 ms,默认 500,设置为 0 则全局禁用缓冲。默认仅仅对 get 请求做缓冲处理。

defaultTypeGuardMessage

类型:string

说明:默认的类型守卫错误提示,仅支持全局配置,默认 “响应数据未能正确识别”,单个 api 可通过传入完整的类型守卫({ guard, message })来定制提示消息。

message

类型:false | (( result: IResponseResult, method: string, url: string, defaultMessage: string ) => string | false | Error | {message: string})

说明:默认情况下,工具函数会输出 message 消息用于提示,当不需要提示时可以设置为 false;

如果需要自定义提示内容,可以传递一个函数,并返回 false 或 字符串; 如果需要指定提示的类型,可以选择返回:

  • Error 对象,则消息格式会被强制以 error 方式提示
  • { message: string } ,则消息格式会被强制以 success 方式提示

responseRule

类型:{ failed: FailedRule, ok: OKRule }

说明:用于指定如何解析响应体内容

  • FailedRule: { resolve, converter?, statusField?, messageField? }

    http失败时 (status <200 || status >= 400) 解析策略

    resolve: "json" | "body"

    解析方式,设置为 json(默认),则可以进一步指定错误消息字段;设置为 body 则将整个 body 解析为错误信息;

    converter: (body: unknown) => unknown

    内容转化方式,默认不转化;可以提供函数进行转化,此时尚未进行类型守卫检查。body内容被 parseJSON 后作为参数传入转化函数。

    statusField: string

    解析状态的字段,仅在 resolve 为 json 时有效,有值的话会替换 response 的 code

    messageField: string | string[]

    解析错误消息的字段,仅在 resolve 为 json 时有效,默认值 "message"

  • OKRule: { resolve, converter?, statusField?, statusOKValue?, dataField?, messageField?, ignoreMessage? }

    http成功时 (200 <= status < 400) 解析策略

    resolve: "json" | "body"

    解析方式,若设置为 json,则可以进一步指定更多字段;若设置为 body(默认),则把整个响应体作为接口返回的数据使用,如果格式化失败,则返回响应的字符串;

    converter: (body: unknown) => unknown

    内容转化方式,默认不转化;可以提供函数进行转化,此时尚未进行类型守卫检查。body内容被 parseJSON 后作为参数传入转化函数。

    statusField: string

    指定表示自定义状态的字段名,默认是 "code"

    statusOKValue: string

    指定表示自定义状态成功时的 value,默认是 "0",如果响应值为数字,则会被转化为字符串进行处理

    dataField: string | true

    指定表示响应数据的字段,默认是 "data",如果设置为 true,则将整个 json body 作为数据内容返回

    messageField: string | string[]

    指定表示提示消息的字段,提示消息可以包括错误消息和成功消息,默认是 "message"

    ignoreMessage: string | string[]

    指定忽略的消息,比如 ok 等,可以设置多个忽略消息,区分大小写

maxRetry

类型:number

说明:当请求发生错误时重试的次数,默认0,即不重试,最大为 10

retryResolve

类型:"network" | "status" | number[] | ((result: IRequestBaseResponse, count: number) => boolean)

说明:重试判断方法,默认是 network

network 表示仅仅当网络错误时才重试,如果请求被取消(aborted)则不重试;

status 表示网络错误或者http 状态码错误时(<200 || >=400)重试;

当设置为 number[] 时,将检查 http 状态码,匹配则重试;

也可以设置为一个重试检查函数,返回 true 则进行重试;

如果需要收集错误的重试信息,可以通过设置 retryResolve 为一个函数来检查或上报请求结果

retryInterval

类型:number | "2EB" | ((retryIndex: number, { url, method, status }) => number)

说明:两次重试的间隔策略,设置为数字(单位 ms)表示固定间隔,设置为函数则可以自定义间隔;默认是 100ms;

其中 retryIndex 从 1 开始,最大为 10;最小时间间隔为 100ms;

特殊值 2EB 表示以 2 为底的指数退避策略,即首次重试等待 0.1 秒,后续分别是 0.2秒,0.4秒,0.8秒 ...

requestTransformer

类型:null | ((data: { headers: Record<string, string>, params: Record<string, string>, method: string, url: string, body: IBaseRequestBody }) => MaybePromise<void | string>)

说明:可用于发送前修改请求相关数据

  • 发送前用于修改 headers 或 params 的函数,headers 和 params 为引用数据,可以直接修改或追加内容;
  • 函数如果返回一个非空字符串,则当作 url 地址使用,原有的 url 地址将被替换;
  • 通常用于全局追加 header 自定义认证信息或签名信息;

errorHandler

类型:null | ((data: { status: number, code: string, method: string, url: string, headers: Record<string, string>, rawError?: Error | ProgressEvent, responseBody: string, sentryError: Error, sentryTags: Record<string, string | number>, sentryExtra: Record<string, unknown> }) => void)

说明:全局错误处理函数,仅仅在 http status 错误时触发,通常用于检查 401 未登录状态进行跳转登录,其中 sentryError / sentryTags / sentryExtra 可用以进行 Sentry 信息上报(示例代码见下);

responseHandler

类型:null | ((result: IResponseResult, method: string, url: string) => void)

说明:请求完成后用于统一检查响应结果,非网络错误时触发,入参的数据均为副本,仅仅可读

messageHandler

类型:null | ((isError: boolean, message: string, code: string, status:number) => void)

说明:全局默认提示函数,isError 表示需要提示的消息是否为错误消息,message 为提示内容,code 为状态描述码或内置错误码(可导出 RequestInternalError 进行对比),status 为 http 状态码

logHandler

类型:null | ((data: IRequestLog) => void)

说明:全局日志打印函数,具体日志信息可参考源码类型声明;

网络请求参数

类型:IRequestOptions

说明:网络请求参数,对于每个最终工具函数都提供有可选的请求参数,且每个字段均可选

method

类型:"GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD"

params

类型:Record<string, unknown>

headers

类型: Record<string, string>

body

类型:Blob | ArrayBuffer | FormData | URLSearchParams | string | Record<string, unknown>

说明:请求要发送的数据,当 method 为 GET / HEAD / DELETE 时,body 无效

credentials

同全局配置,仅本次请求有效,可选 "omit" | "same-origin" | "include",如果跨域需要携带 cookie,可以设置为 include。默认跟随全局设置

timeout

同全局配置,仅本次请求有效,默认跟随全局设置

abort

类型:AbortSignal,用于主动中断请求;

  • 当请求结束时无效;
  • 仅浏览器环境有效,
  • 不支持 AbortSignal 的浏览器可以引入 https://www.npmjs.com/package/abortcontroller-polyfill 或 https://polyfill.io/v3/polyfill.min.js?features=AbortController

message

同全局配置,仅本次请求有效,默认跟随全局设置

responseRule

同全局配置,设定的解析规则仅本次请求有效,默认跟随全局设置

maxRetry

同全局配置,仅本次请求有效,设置最大重试次数,默认跟随全局设置

retryResolve

同全局配置,仅本次请求有效,设置重试判断策略,默认跟随全局设置

retryInterval

同全局配置,仅本次请求有效,默认跟随全局设置

cacheTTL

同全局配置,仅本次请求有效,默认跟随全局设置

cacheResolve

类型:() => string | false

说明:用于返回请求缓冲的 key,返回 false 或空字符串则不缓冲,返回非空字符串则作为缓冲 key,默认仅仅对 get 请求做缓冲处理

响应内容

所有请求均返回同样的结构(包括网络错误或状态码错误时)其结构字段如下

ok

类型:boolean

说明:表示当前请求是否成功,包括检测 http status, responseRule 以及类型守卫

status

类型:number

说明:表示响应的 http 状态码,请求被取消返回 0,网络错误或其他异常情况返回负数(具体数值无含义)

code

类型:string

说明:表示当前请求的状态信息,其可能值有

  • http statusText 当请求完成且无自定义错误码时,可能为空字符串
  • responseRule 中自定义的错误码字段所传递的值
  • "Aborted" 或 "Unknown" 网络错误或取消等异常情况,详细参见 RequestInternalError

message

类型:string

说明:响应结果的提示消息,不受 IRequestOptions.message 影响

headers

类型:Record<string, string | undefined>

说明:响应的头信息,全部字段名均被转成小写

data

类型:unknown | T | null

说明:响应的数据内容,其可能值为:

  • unknown:如果不提供类型守卫,则返回 unknown
  • null:网络请求错误、类型守卫检查失败、服务器没有返回正确格式的 json 数据,则返回 null
  • T: 如果成功返回并通过类型守卫检查,则返回类型守卫对应的类型

类型守卫

类型守卫是一个返回 boolean 的特殊函数,用于检查某个 unknown 的数据是否为指定类型的数据,对于 ts 来说,这是确保远程数据类型安全的必要措施。其定义如下

type TypeGuardFn<T> = (value: unknown) => value is T;
type TypeGuard<T> = {
    guard: TypeGuardFn<T>;
    message: string; /* 当检查失败时的错误提示信息 */
};
type TypeGuardParam<T> = TypeGuard<T> | TypeGuardFn<T>

Request函数

request<T>(url: string, options?: IRequestOptions)

底层实现的 request 工具函数,未绑定类型守卫处理,返回的数据类型固定为 unknown;同时也未对请求做任何缓存处理;通常情况推荐使用以下的包装函数:get / post / head / del / put / patch

get<T>(url: string, typeGard?: TypeGuardParam<T> | null, options?: IRequestOptions)

  • url: 请求的资源路径,如果需要跳过全局 baseURL 设置,可以传递完整 url 地址
  • typeGuard: 可选类型守卫,如果设置为 null,则返回的内容为 unkonwn,否则就是经过类型守卫检查后的类型化数据,推荐传递类型守卫
  • options: 可选请求配置参数

注意,get 请求默认设置 500ms 缓存,即对同一个请求(url+params)在 500ms 内不再重复发起请求,而是直接返回上一次的结果,其中 params 会从 options.params 以及 url 中查找

post(url: string, data: RequstBody, typeGard?: TypeGuardParam<T> | null, options?: IRequestOptions)

  • url: 请求的资源路径,如果需要跳过全局 baseURL 设置,可以传递完整 url 地址
  • data: 请求发送的数据,会覆盖 IRequestOptions.body
  • typeGuard: 可选类型守卫,如果设置为 null,则返回的内容为 unkonwn,否则就是经过类型守卫检查后的类型化数据,推荐传递类型守卫,除非对响应内容不关心(比如 httpStatus 为 204 或 202)
  • options: 可选请求配置参数

Other

head(url, options?) head 方法不支持响应body,也就无需 typeGuard

del(url, typeGard?, options?)

put(url, data, typeGard?, options?)

patch(url, data, typeGard?, options?)

特殊函数

工具还提供了三个特殊函数以应对不同的场景需求,且限于浏览器环境使用:

upload(url: string, files: Record<string, Blob>, options?)

因为 fetch 不支持上传进度信息,故使用 xhr 函数包装,支持带有上传进度信息的 upload 函数,以满足特定场景下的大文件上传需求;

其可选 options 不支持重试,其 body 类型限制为 Record<string, unknown>,并且随着 formData 发送;同时新增进度信息配置:

onUploadProgress?: (progress: { total: number; loaded: number }) => void

jsonp<T>(url: string, typeGuard: TypeGuardFn<T>, params?: Record<string, string|number|boolean>)

以 script 方式加载远程资源,并通过 callback 回调接收远程数据,必须提供类型守卫;

jsonx<T>(url: string, typeGuard: TypeGuardFn<T>, params?: Record<string, string|number|boolean>)

以 script 方式加载远程资源,并通过 var(全局变量)接收远程数据,必须提供类型守卫;

通常情况下,并不推荐使用 jsonp 和 jsonx 来请求数据,跨域请求请优先使用后端 CORS 方案;

更多示例

使用 form 发送数据(所有数据均可以序列化为字符串)

const encodeFormData: string[];
for (const key in data) {
  encodeFormData.push(`${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`);
}
// 需要手工指定Content-Type
const { ok, data } = await post(url, encodeFormData.join("&"), typeGuard, {
  headers: {
    "Content-Type": "application/x-www-form-urlencoded",
  },
});

使用 formData 发送数据(可以含有二进制文件),如果是想要带进度的上传,可以使用 upload 方法

const formData = new FormData();
for (const key in data) {
  formData.append(key, data[key]);
}
// 传递 FormData 实例时,无须手工指定 Content-Type
const { ok, data } = await post(url, formData, typeGuard);

修改默认的异常提示(通常是不必要的)

setGlobalConfig({
  message: function ({ code, status, message }, method, url, defaultMsg) {
    if (status === 401) {
      return "";
    }
    if (status === 404) {
      return `${method} ${url} 接口未定义`;
    }
    if (status >= 500 && status <= 599) {
      return "🚨 服务器错误,请稍候再试";
    }
    if (code === "Unknown") {
      return `⛔ ${url} 出现未知错误,请稍候再试`;
    }
    return message;
  },
});

Sentry 信息上报

import { captureException } from "@sentry/vue";

setGlobalConfig({
  errorHandler({ status, sentryError, sentryTags, sentryExtra }) {
    if (status === 401) {
      return;
    }
    captureException(sentryError, {
      tags: sentryTags,
      extra: sentryExtra,
    });
  },
});