ofetch logo

ofetch

更强大的 Fetch API 封装,跨平台通用、自动 JSON 解析、内置重试与超时机制。

HTTP请求API客户端Fetch封装跨平台

ofetch 是由 UnJS 团队开发的跨平台 HTTP 请求库,定位为原生 Fetch 的增强替代品。提供自动 JSON 解析、智能错误处理、请求重试、超时控制、拦截器等功能,在浏览器/Node.js/Deno/Bun/Edge Runtime 中一致运行。作为 Nuxt 3 的内置 HTTP 客户端,gzip 仅约 3.8 KB,GitHub 约 5,300 Stars。

ofetch

更强大的 Fetch API 封装,跨平台通用、自动 JSON 解析、内置重试与超时机制。

技术简介说明

ofetch 是由 UnJS 团队开发的跨平台 HTTP 请求库,定位为原生 fetch API 的增强替代品。它在保留原生 fetch 接口的同时,补充了自动 JSON 解析、智能错误处理、请求重试、超时控制、拦截器等实用能力,并且能够在浏览器、Node.js、Deno、Bun 以及各类 Edge Runtime(Cloudflare Workers、Vercel Edge 等)中一致运行。

作为 Nuxt 3 的内置 HTTP 客户端($fetch / useFetch 底层即 ofetch),它已深度集成于 Vue/Nuxt 生态,同时在任意 JavaScript/TypeScript 项目中都可独立使用。2026 年 ofetch 仍保持活跃维护,最新稳定版 v1.5.1 于 2025 年 11 月发布,v2.0.0-alpha 正在开发中。

基本信息

项目信息
名称ofetch(前身为 ohmyfetch)
最新版本v1.5.1(2025-11-01);v2.0.0-alpha.3(2025-10-28)
GitHubunjs/ofetch
Stars~5,300+
LicenseMIT
npmofetch
Bundle Sizegzip ~3.8 KB(核心);含依赖 ~18.7 KB
维护者UnJS 团队(Pooya ParsaSébastien Chopin 等 Nuxt 核心成员)
运行时支持浏览器、Node.js 18+、Deno、Bun、Cloudflare Workers、Vercel Edge 等
TypeScript原生支持,类型完整
周下载量~500 万+(2026 年数据)

快速上手

安装

# npm
npm install ofetch
 
# pnpm
pnpm add ofetch
 
# yarn
yarn add ofetch
 
# 在 Nuxt 3 中无需安装,已内置

基础用法

import { ofetch } from 'ofetch'
 
// 自动 JSON 解析(响应会自动调用 .json())
const users = await ofetch('/api/users')
 
// 带类型
interface User {
  id: number
  name: string
}
const user = await ofetch<User>('/api/users/1')
 
// 使用 $fetch 别名(Nuxt 中的常用写法)
import { $fetch } from 'ofetch'
const data = await $fetch('/api/data')

创建实例

import { createFetch } from 'ofetch'
 
const api = createFetch({
  baseURL: 'https://api.example.com',
  headers: {
    Authorization: 'Bearer xxx'
  }
})
 
const users = await api('/users')

最小示例(Nuxt 3)

<script setup>
// useFetch 底层即为 ofetch,支持 SSR + 响应式
const { data, error } = await useFetch('/api/users')
</script>

核心概念与架构

ofetch 的架构分为三层:

  1. 核心层(fetch.ts):对原生 fetch 的封装,处理请求拦截、响应解析、错误转换。内部使用 node-fetch-native 保证跨平台一致性,使用 destr 进行智能 JSON 解析。

  2. 配置层(createFetch):通过工厂函数创建可复用的请求实例,支持 baseURL、默认 headers、全局拦截器等配置。

  3. 运行时适配层(node-fetch-native):自动检测当前运行环境,在 Node.js < 18 时 polyfill fetch,在新版 Node.js、Deno、Bun 和浏览器中直接使用原生 fetch。

┌─────────────────────────────────────┐
│  ofetch / $fetch / createFetch      │  ← 用户接口
├─────────────────────────────────────┤
│  fetch.ts(核心封装)                │  ← 拦截器、重试、超时、解析
├─────────────────────────────────────┤
│  destr(JSON 解析)                 │  ← 智能反序列化
│  node-fetch-native(跨平台 fetch)  │  ← 运行时适配
│  ufo(URL 工具)                    │  ← URL 拼接与处理
└─────────────────────────────────────┘

核心特性

  1. 自动 JSON 解析:使用 destr 智能解析响应体,无需手动调用 .json();解析失败时自动降级为文本。

  2. 跨平台通用:一套代码在浏览器、Node.js、Deno、Bun、Edge Runtime 中均可运行,无需额外配置。

  3. 内置请求重试:支持配置 retry 次数、retryDelay 延迟、retryStatusCodes(默认重试 408、409、425、429、500、502、503、504),指数退避可选。

  4. 超时控制:通过 timeout 选项设置请求超时时间(毫秒),超时后自动 abort 请求。

  5. 请求/响应拦截器:支持 onRequestonRequestErroronResponseonResponseError 四个生命周期钩子,可统一处理 token 注入、日志、错误格式化等。

  6. 智能错误处理:HTTP 错误状态码自动抛出 FetchError,包含结构化错误信息(statusCodedatastatusMessage),便于统一拦截。

  7. TypeScript 原生支持:完整的类型推导,支持泛型约束响应类型,CreateFetchOptions 类型导出。

  8. Query 参数处理:自动序列化 query 对象为 URL 参数,支持嵌套对象与数组。

  9. BaseURL 合并:使用 ufo 库智能拼接 baseURL 与请求路径,处理多余的斜杠。

  10. FormData / Blob 支持:自动识别请求体类型,正确设置 Content-Type

生态图

                    ┌──────────────────┐
                    │      Nuxt 3      │
                    │  useFetch/$fetch │
                    └────────┬─────────┘
                             │ 底层依赖
                             ▼
┌──────────┐    ┌──────────────────┐    ┌──────────────┐
│  destr   │◄───│     ofetch       │───►│    ufo       │
│ JSON解析  │    │  (核心请求库)    │    │  URL 工具     │
└──────────┘    └────────┬─────────┘    └──────────────┘
                         │
                         ▼
                ┌──────────────────┐
                │ node-fetch-native│
                │  跨平台 fetch     │
                └──────────────────┘

UnJS 生态关联:
├── ofetch        — HTTP 请求
├── h3            — HTTP 服务端框架
├── nitro         — 服务端引擎(Nuxt 后端)
├── unenv         — 环境适配层
├── destr         — 安全 JSON 解析
├── ufo           — URL 工具函数
└── consola       — 跨平台日志

适用场景

  1. Nuxt 3 / Vue 项目:ofetch 是 Nuxt 的默认 HTTP 客户端,useFetch$fetchuseAsyncData 均基于它,无需额外引入。

  2. 全栈/SSR 应用:需要同一份请求代码在 Node.js 服务端和浏览器客户端通用运行。

  3. Edge Runtime / Serverless:在 Cloudflare Workers、Vercel Edge Functions、Deno Deploy 等边缘环境中使用,体积小、启动快。

  4. 轻量 API 客户端封装:需要基于 fetch 构建带拦截器、重试、统一错误处理的 API 层,但不想引入 axios 等大型库。

  5. Monorepo / 多环境项目:需要同一请求库在多种运行时(Node/Browser/Worker)中表现一致。

  6. TypeScript 项目:需要完整的类型推导和泛型支持。

  7. 微前端/嵌入式场景:对 bundle 体积敏感,需要轻量级请求方案。

开发与工程化

项目结构

ofetch/
├── src/
│   ├── fetch.ts        # 核心实现
│   ├── error.ts        # FetchError 类
│   ├── types.ts        # TypeScript 类型定义
│   └── index.ts        # 导出入口
├── test/               # 测试用例(vitest)
├── package.json
└── tsconfig.json

构建工具

  • 使用 unbuild 构建,同时输出 ESM 和 CJS 格式
  • 测试框架:vitest
  • 代码规范:遵循 UnJS 统一风格

本地开发

git clone https://github.com/unjs/ofetch.git
cd ofetch
pnpm install
pnpm build    # 构建
pnpm test     # 运行测试

版本发布

遵循语义化版本(SemVer),使用 changelogen 自动生成 changelog。

性能与安全

性能

  • 体积极小:gzip ~3.8 KB(核心),远小于 axios(~13.5 KB gzip)和 undici(~155 KB gzip)
  • 零 polyfill 开销:在支持原生 fetch 的环境中直接使用,无额外性能损耗
  • 高效 JSON 解析:使用 destr 进行安全的 JSON 解析,避免 JSON.parse 的异常风险
  • 无运行时依赖树膨胀:仅依赖 destrufonode-fetch-native 三个轻量包

安全

  • 使用 destr 替代 JSON.parse,防止原型污染和解析异常
  • 自动处理 Content-Type,减少手动设置带来的安全风险
  • 错误响应不会泄露敏感堆栈信息
  • 支持 AbortController,可取消请求防止资源泄露

技术对比

特性ofetchaxioskynode-fetch原生 fetch
Bundle (gzip)~3.8 KB~13.5 KB~7.0 KB~22.6 KB0(内置)
跨平台✅ 全平台✅ 浏览器 + Node✅ 仅浏览器❌ 仅 Node⚠️ Node 18+
自动 JSON 解析
请求重试✅ 内置❌ 需封装✅ 内置
超时控制✅ 内置✅ 内置✅ 内置
拦截器✅ 4 个钩子✅ 请求/响应✅ hooks
TypeScript✅ 原生✅ 有类型✅ 原生✅ @types✅ 内置
SSR 兼容✅ 开箱即用⚠️ 需适配❌ 不支持⚠️
Nuxt 集成✅ 内置❌ 需安装❌ 需安装❌ 需安装⚠️ 手动
取消请求✅ AbortController✅ CancelToken

选型建议

  • Nuxt 3 项目:首选 ofetch(已内置,SSR 兼容)
  • 浏览器项目 + 轻量需求:ky 或 ofetch 均可
  • 已有 axios 代码库:无需迁移,但新项目可考虑 ofetch
  • Node.js 服务端独立使用:ofetch 或 undici
  • 极致体积要求:原生 fetch + 自行封装

最佳实践

1. 统一创建实例

// utils/api.ts
import { createFetch } from 'ofetch'
 
export const api = createFetch({
  baseURL: import.meta.env.VITE_API_BASE || '/api',
  onRequest({ options }) {
    // 统一注入 token
    const token = localStorage.getItem('token')
    if (token) {
      options.headers.set('Authorization', `Bearer ${token}`)
    }
  },
  onResponseError({ response }) {
    // 统一处理 401
    if (response.status === 401) {
      navigateTo('/login')
    }
  }
})

2. 合理配置重试

// 幂等请求开启重试,非幂等请求关闭
const data = await ofetch('/api/users', {
  retry: 3,
  retryDelay: 1000,
  retryStatusCodes: [408, 429, 500, 502, 503, 504]
})
 
// POST 请求默认不重试,但可显式开启
await ofetch('/api/orders', {
  method: 'POST',
  body: { item: 'xxx' },
  retry: false  // 非幂等操作,关闭重试
})

3. 超时与错误处理

try {
  const data = await ofetch('/api/slow-endpoint', {
    timeout: 5000  // 5 秒超时
  })
} catch (error) {
  if (error.name === 'AbortError') {
    console.log('请求超时')
  } else if (error.name === 'FetchError') {
    console.log('HTTP 错误:', error.statusCode)
  }
}

4. Nuxt 3 中正确使用

<script setup>
// ✅ 在 setup 顶层使用 useFetch(SSR 友好)
const { data: users } = await useFetch('/api/users')
 
// ✅ 在事件处理函数中使用 $fetch
async function handleSubmit() {
  await $fetch('/api/submit', {
    method: 'POST',
    body: formData
  })
}
 
// ❌ 不要在 setup 顶层用 $fetch(不会自动 SSR 序列化)
// const data = await $fetch('/api/data')  // 不推荐
</script>

5. 类型安全的 API 封装

// api/users.ts
import { ofetch } from 'ofetch'
 
interface User {
  id: number
  name: string
  email: string
}
 
interface UserListResponse {
  data: User[]
  total: number
}
 
export async function getUsers(page = 1): Promise<UserListResponse> {
  return ofetch<UserListResponse>('/api/users', {
    query: { page, pageSize: 20 }
  })
}

技术局限与边界

  1. 不支持请求取消的细粒度控制:依赖 AbortController,无法像 axios 的 CancelToken 那样链式取消多个请求。

  2. 浏览器专属特性缺失:不支持 XHR 特有的功能,如上传进度监听(onUploadProgress),需要上传进度时使用原生 XHR 或 axios。

  3. v2.0.0 尚未稳定:v2.0.0-alpha 正在开发中,API 可能存在 breaking changes,生产环境建议使用 v1.x 稳定版。

  4. 社区生态相对集中:主要由 UnJS/Nuxt 团队维护,社区贡献者相比 axios 较少,插件生态不如 axios 丰富。

  5. 文档相对简略:官方文档(README + Mintlify 站点)覆盖了核心 API,但高级用法和迁移指南不如 axios 详尽。

  6. 调试支持有限:不像 axios 有 DevTools 插件或浏览器网络面板的深度集成,ofetch 请求在调试工具中的展示依赖浏览器原生网络面板。

  7. Node.js 旧版本需要 polyfill:Node.js < 18 依赖 node-fetch-native 提供的 polyfill,可能引入边缘兼容问题。

学习资源

官方资源

Nuxt 集成

社区与教程

视频

2026 年现状

维护状态

ofetch 在 2026 年仍处于活跃维护状态:

  • v1.5.1(2025-11-01)为当前最新稳定版,已在生产环境广泛使用
  • v2.0.0-alpha.3(2025-10-28)正在开发中,预计将带来 breaking changes
  • GitHub 上有持续的 Issue 和 PR 活动,UnJS 团队响应及时

生态地位

  • Nuxt 3/4 默认 HTTP 客户端:只要 Nuxt 保持增长,ofetch 的使用量就会持续扩大
  • Nuxt 周下载量超 500 万,ofetch 作为其内置依赖同步增长
  • UnJS 生态核心组件:与 h3、nitro、unenv 等包协同,构成全栈 JavaScript 基础设施
  • Edge Runtime 友好:在 Vercel、Cloudflare 等边缘平台的使用场景持续增加

发展趋势

  • v2.0.0 预计带来改进:可能包括更好的类型支持、性能优化和 API 精简
  • 原生 fetch 标准化:随着 Node.js 18+ 原生 fetch 普及,ofetch 的 node-fetch-native 依赖将逐步弱化
  • 竞争格局:面临原生 fetch 标准化(减少封装需求)、ky(浏览器场景)、undici(Node.js 高性能场景)的竞争,但凭借 Nuxt 生态集成和跨平台一致性保持独特优势

推荐策略

  • 新项目 + Nuxt:直接使用内置 ofetch,无需犹豫
  • 新项目 + 非 Nuxt:ofetch 是轻量跨平台请求的优质选择
  • 已有 axios 项目:无紧急迁移必要,但可在新增模块中逐步引入 ofetch
  • 关注 v2.0.0 发布:计划迁移的项目应跟踪 alpha 版本的 breaking changes