8000 up-fetch/README_ZH.md at master · L-Blondy/up-fetch · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Latest commit

 

History

History
613 lines (456 loc) · 18.2 KB

README_ZH.md

File metadata and controls

613 lines (456 loc) · 18.2 KB

upfetch - 高级 fetch 客户端构建器

upfetch


npm version npm bundle size license commit activity downloads per month


upfetch 是一个高级的 fetch 客户端构建器,具有标准模式验证、自动响应解析、智能默认值等功能。旨在使数据获取类型安全且开发人员友好,同时保持熟悉的 fetch API。

警告 此中文翻译由人工智能生成。如果您发现任何错误或有改进建议,欢迎提交 Pull Request。

目录

➡️ 亮点

  • 🚀 轻量级 - 压缩后仅 1.2kB,无依赖
  • 🔒 类型安全 - 使用 zodvalibotarktype 验证 API 响应
  • 🛠️ 实用的 API - 使用对象作为 paramsbody,自动获取解析后的响应
  • 🎨 灵活配置 - 一次设置 baseUrlheaders 等默认值,随处使用
  • 🤝 熟悉的使用方式 - 与 fetch 相同的 API,但具有额外选项和合理的默认值

➡️ 快速开始

npm i up-fetch

创建新的 upfetch 实例:

import { up } from 'up-fetch'

export const upfetch = up(fetch)

使用模式验证进行 fetch 请求:

import { upfetch } from './upfetch'
import { z } from 'zod'

const user = await upfetch('https://a.b.c/users/1', {
   schema: z.object({
      id: z.number(),
      name: z.string(),
      avatar: z.string().url(),
   }),
})

响应已经基于模式进行了解析和正确的类型推断

upfetch 扩展了原生 fetch API,这意味着所有标准的 fetch 选项都可用。

➡️ 主要特性

✔️ 请求配置

创建实例时为所有请求设置默认值:

const upfetch = up(fetch, () => ({
   baseUrl: 'https://a.b.c',
   timeout: 30000,
}))

查看 API 参考 获取完整的选项列表。

✔️ 简单查询参数

👎 使用原生 fetch:

fetch(
   `https://api.example.com/todos?search=${search}&skip=${skip}&take=${take}`,
)

👍 使用 upfetch

upfetch('/todos', {
   params: { search, skip, take },
})

使用 serializeParams 选项自定义查询参数序列化。

✔️ 自动处理请求体

👎 使用原生 fetch:

fetch('https://api.example.com/todos', {
   method: 'POST',
   headers: { 'Content-Type': 'application/json' },
   body: JSON.stringify({ title: 'New Todo' }),
})

👍 使用 upfetch

upfetch('/todos', {
   method: 'POST',
   body: { title: 'New Todo' },
})

upfetch 也支持所有 fetch body 类型

查看 serializeBody 选项自定义请求体序列化。

✔️ 模式验证

由于 upfetch 遵循 Standard Schema Specification,它可以与任何实现该规范的模式库一起使用。
查看完整列表 这里

👉 使用 zod 3.24+

import { z } from 'zod'

const posts = await upfetch('/posts/1', {
   schema: z.object({
      id: z.number(),
      title: z.string(),
   }),
})

👉 使用 valibot 1.0+

import { object, string, number } from 'valibot'

const posts = await upfetch('/posts/1', {
   schema: object({
      id: number(),
      title: string(),
   }),
})

✔️ 生命周期钩子

使用简单的钩子控制请求/响应生命周期:

const upfetch = up(fetch, () => ({
   onRequest: (options) => {
      // 在发出请求之前调用,可以在此处修改选项
   },
   onSuccess: (data, options) => {
      // 请求成功完成时调用
   },
   onError: (error, options) => {
      // 请求失败时调用
   },
}))

✔️ 超时设置

为单个请求设置超时:

upfetch('/todos', {
   timeout: 3000,
})

为所有请求设置默认超时:

const upfetch = up(fetch, () => ({
   timeout: 5000,
}))

✔️ 错误处理

👉 ResponseError

response.okfalse 时抛出。
使用 isResponseError 识别此错误类型。

import { isResponseError } from 'up-fetch'

try {
   await upfetch('/todos/1')
} catch (error) {
   if (isResponseError(error)) {
      console.log(error.status)
   }
}
  • 使用 parseRejected 选项抛出自定义错误。
  • 使用 reject 选项决定何时抛出错误。

👉 ValidationError

当模式验证失败时抛出。
使用 isValidationError 识别此错误类型。

import { isValidationError } from 'up-fetch'

try {
   await upfetch('/todos/1', { schema: todoSchema })
} catch (error) {
   if (isValidationError(error)) {
      console.log(error.issues)
   }
}

➡️ 使用方法

✔️ 身份验证

通过设置默认 header 轻松为所有请求添加身份验证:

const upfetch = up(fetch, () => ({
   headers: { Authorization: localStorage.getItem('bearer-token') },
}))

在每次请求之前从 localStorage 获取 bearer token。

✔️ 删除默认选项

只需传递 undefined

upfetch('/todos', {
   signal: undefined,
})

✔️ 表单数据

form 获取 FormData。

const form = document.querySelector('#my-form')

upfetch('/todos', {
   method: 'POST',
   body: new FormData(form),
})

或从对象创建 FormData:

import { serialize } from 'object-to-formdata'

const upfetch = up(fetch, () => ({
   serializeBody: (body) => serialize(body),
}))

upfetch('https://a.b.c', {
   method: 'POST',
   body: { file: new File(['foo'], 'foo.txt') },
})

✔️ HTTP 代理

由于 upfetch"fetch 无关的",你可以使用 undici 代替原生 fetch 实现。

在单个请求中:

import { fetch, Agent } from 'undici'

const upfetch = up(fetch)

const data = await upfetch('https://a.b.c', {
   dispatcher: new Agent({
      keepAliveTimeout: 10,
      keepAliveMaxTimeout: 10,
   }),
})

在所有请求中:

import { fetch, Agent } from 'undici'

const upfetch = up(fetch, () => ({
   dispatcher: new Agent({
      keepAliveTimeout: 10,
      keepAliveMaxTimeout: 10,
   }),
}))

✔️ 多个 fetch 客户端

你可以创建多个具有不同默认值的 upfetch 实例:

const fetchJson = up(fetch)

const fetchBlob = up(fetch, () => ({
   parseResponse: (res) => res.blob(),
}))

const fetchText = up(fetch, () => ({
   parseResponse: (res) => res.text(),
}))

➡️ 高级用法

✔️ 错误作为值

虽然 Fetch API 在响应不正常时不会抛出错误,但 upfetch 会抛出 ResponseError

如果你更愿意将错误作为值处理,将 reject 设置为返回 false
这允许你自定义 parseResponse 函数以结构化格式返回成功数据和错误响应。

const upfetch = up(fetch, () => ({
   reject: () => false,
   parseResponse: async (response) => {
      const json = await response.json()
      return response.ok
         ? { data: json, error: null }
         : { data: null, error: json }
   },
}))

使用方法:

const { data, error } = await upfetch('/users/1')

✔️ 自定义响应解析

默认情况下,upfetch 能够自动解析 jsontext 成功响应。

reject 返回 false 时调用 parseResponse 方法。 你可以使用该选项解析其他响应类型。

const upfetch = up(fetch, () => ({
   parseResponse: (response) => response.blob(),
}))

💡 注意,只有当 reject 返回 false 时才会调用 parseResponse 方法。

✔️ 自定义响应错误

默认情况下,当 reject 返回 true 时,upfetch 会抛出 ResponseError

如果你想抛出自定义错误,可以向 parseRejected 选项传递一个函数。

const upfetch = up(fetch, () => ({
   parseRejected: async (response) => {
      const status = response.status
      const data = await response.json()
      return new CustomError(status, data)
   },
}))

✔️ 自定义参数序列化

默认情况下,upfetch 使用 URLSearchParams 序列化参数。

你可以通过向 serializeParams 选项传递函数来自定义参数序列化。

import queryString from 'query-string'

const upfetch = up(fetch, () => ({
   serializeParams: (params) => queryString.stringify(params),
}))

✔️ 自定义请求体序列化

默认情况下,upfetch 使用 JSON.stringify 序列化普通对象。

你可以通过向 serializeBody 选项传递函数来自定义请求体序列化。它允许你:

  • 限制有效的请求体类型,通过类型化其第一个参数
  • 将请求体转换为有效的 BodyInit 类型

以下示例展示如何将有效请求体类型限制为 Record<string, any> 并使用 JSON.stringify 序列化:

// 将请求体类型限制为 Record<string, any> 并序列化
const upfetch = up(fetch, () => ({
   serializeBody: (body: Record<string, any>) => JSON.stringify(body),
}))

// ❌ 类型错误:请求体不是 Record<string, any>
upfetch('https://a.b.c/todos', {
   method: 'POST',
   body: [['title', 'New Todo']],
})

// ✅ 使用 Record<string, any> 正常工作
upfetch('https://a.b.c/todos', {
   method: 'POST',
   body: { title: 'New Todo' },
})

以下示例使用 superjson 序列化请求体。有效的请求体类型从 SuperJSON.stringify 推断。

import SuperJSON from 'superjson'

const upfetch = up(fetch, () => ({
   serializeBody: SuperJSON.stringify,
}))

✔️ 基于请求的默认值

默认选项接收 fetcher 参数,这允许你根据实际请求定制默认值。

const upfetch = up(fetch, (input, options) => ({
   baseUrl: 'https://example.com/',
   headers: {
      // 仅为受保护路由添加身份验证
      Authorization:
         typeof input === 'string' && input.startsWith('/api/protected/')
            ? `Bearer ${getToken()}`
            : undefined,
   },
   // 仅为公共端点添加跟踪参数
   params: {
      trackingId:
         typeof input === 'string' && input.startsWith('/public/')
            ? crypto.randomUUID()
            : undefined,
   },
   // 为长时间运行的操作增加超时时间
   timeout:
      typeof input === 'string' && input.startsWith('/export/') ? 30000 : 5000,
}))

➡️ API 参考

up(fetch, getDefaultOptions?)

创建具有可选默认选项的新 upfetch 实例。

function up(
   fetchFn: typeof globalThis.fetch,
   getDefaultOptions?: (fetcherOptions: FetcherOptions) => DefaultOptions,
): UpFetch
选项 签名 描述
baseUrl string 所有请求的基础 URL。
params object 默认查询参数。
onRequest (options) => void 在发出请求之前执行。
onError (error, options) => void 发生错误时执行。
onSuccess (data, options) => void 请求成功完成时执行。
parseResponse (response, options) => data 默认成功响应解析器。
如果省略,将自动解析 jsontext 响应。
parseRejected (response, options) => error 默认错误响应解析器。
如果省略,将自动解析 jsontext 响应。
serializeBody (body) => BodyInit 默认请求体序列化器。
通过类型化其第一个参数限制有效的 body 类型。
serializeParams (params) => string 默认查询参数序列化器。
timeout number 默认超时时间(毫秒)。
reject (response) => boolean 决定何时拒绝响应。
...以及所有其他 fetch 选项

upfetch(url, options?)

使用给定选项发出 fetch 请求。

function upfetch(
   url: string | URL | Request,
   options?: FetcherOptions,
): Promise<any>

选项:

选项 签名 描述
baseUrl string 请求的基础 URL。
params object 查询参数。
parseResponse (response, options) => data 成功响应解析器。
parseRejected (response, options) => error 错误响应解析器。
schema StandardSchemaV1 用于验证响应的模式。
模式必须遵循 Standard Schema Specification
serializeBody (body) => BodyInit 请求体序列化器。
通过类型化其第一个参数限制有效的 body 类型。
serializeParams (params) => string 查询参数序列化器。
timeout number 超时时间(毫秒)。
reject (response) => boolean 决定何时拒绝响应。
...以及所有其他 fetch 选项

isResponseError(error)

检查错误是否为 ResponseError

isValidationError(error)

检查错误是否为 ValidationError

isJsonifiable(value)

确定值是否可以安全转换为 json

以下被认为是可 JSON 化的:

  • 普通对象
  • 数组
  • 具有 toJSON 方法的类实例

➡️ 功能比较

查看功能比较表,了解 upfetch 与其他获取库的比较。


➡️ 环境支持

  • ✅ 浏览器 (Chrome, Firefox, Safari, Edge)
  • ✅ Node.js (20.3.0+)
  • ✅ Bun
  • ✅ Deno
  • ✅ Cloudflare Workers
  • ✅ Vercel Edge Runtime



分享到:

s Share on Twitter



0