ofetch
更强大的 Fetch API 封装,跨平台通用、自动 JSON 解析、内置重试与超时机制。
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) |
| GitHub | unjs/ofetch |
| Stars | ~5,300+ |
| License | MIT |
| npm | ofetch |
| Bundle Size | gzip ~3.8 KB(核心);含依赖 ~18.7 KB |
| 维护者 | UnJS 团队(Pooya Parsa、Sé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 的架构分为三层:
-
核心层(fetch.ts):对原生
fetch的封装,处理请求拦截、响应解析、错误转换。内部使用node-fetch-native保证跨平台一致性,使用destr进行智能 JSON 解析。 -
配置层(createFetch):通过工厂函数创建可复用的请求实例,支持
baseURL、默认headers、全局拦截器等配置。 -
运行时适配层(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 拼接与处理
└─────────────────────────────────────┘
核心特性
-
自动 JSON 解析:使用
destr智能解析响应体,无需手动调用.json();解析失败时自动降级为文本。 -
跨平台通用:一套代码在浏览器、Node.js、Deno、Bun、Edge Runtime 中均可运行,无需额外配置。
-
内置请求重试:支持配置
retry次数、retryDelay延迟、retryStatusCodes(默认重试 408、409、425、429、500、502、503、504),指数退避可选。 -
超时控制:通过
timeout选项设置请求超时时间(毫秒),超时后自动 abort 请求。 -
请求/响应拦截器:支持
onRequest、onRequestError、onResponse、onResponseError四个生命周期钩子,可统一处理 token 注入、日志、错误格式化等。 -
智能错误处理:HTTP 错误状态码自动抛出
FetchError,包含结构化错误信息(statusCode、data、statusMessage),便于统一拦截。 -
TypeScript 原生支持:完整的类型推导,支持泛型约束响应类型,
CreateFetchOptions类型导出。 -
Query 参数处理:自动序列化
query对象为 URL 参数,支持嵌套对象与数组。 -
BaseURL 合并:使用
ufo库智能拼接baseURL与请求路径,处理多余的斜杠。 -
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 — 跨平台日志
适用场景
-
Nuxt 3 / Vue 项目:ofetch 是 Nuxt 的默认 HTTP 客户端,
useFetch、$fetch、useAsyncData均基于它,无需额外引入。 -
全栈/SSR 应用:需要同一份请求代码在 Node.js 服务端和浏览器客户端通用运行。
-
Edge Runtime / Serverless:在 Cloudflare Workers、Vercel Edge Functions、Deno Deploy 等边缘环境中使用,体积小、启动快。
-
轻量 API 客户端封装:需要基于 fetch 构建带拦截器、重试、统一错误处理的 API 层,但不想引入 axios 等大型库。
-
Monorepo / 多环境项目:需要同一请求库在多种运行时(Node/Browser/Worker)中表现一致。
-
TypeScript 项目:需要完整的类型推导和泛型支持。
-
微前端/嵌入式场景:对 bundle 体积敏感,需要轻量级请求方案。
开发与工程化
项目结构
ofetch/
├── src/
│ ├── fetch.ts # 核心实现
│ ├── error.ts # FetchError 类
│ ├── types.ts # TypeScript 类型定义
│ └── index.ts # 导出入口
├── test/ # 测试用例(vitest)
├── package.json
└── tsconfig.json
构建工具
本地开发
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的异常风险 - 无运行时依赖树膨胀:仅依赖
destr、ufo、node-fetch-native三个轻量包
安全
- 使用
destr替代JSON.parse,防止原型污染和解析异常 - 自动处理
Content-Type,减少手动设置带来的安全风险 - 错误响应不会泄露敏感堆栈信息
- 支持
AbortController,可取消请求防止资源泄露
技术对比
| 特性 | ofetch | axios | ky | node-fetch | 原生 fetch |
|---|---|---|---|---|---|
| Bundle (gzip) | ~3.8 KB | ~13.5 KB | ~7.0 KB | ~22.6 KB | 0(内置) |
| 跨平台 | ✅ 全平台 | ✅ 浏览器 + 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 }
})
}技术局限与边界
-
不支持请求取消的细粒度控制:依赖
AbortController,无法像 axios 的CancelToken那样链式取消多个请求。 -
浏览器专属特性缺失:不支持 XHR 特有的功能,如上传进度监听(
onUploadProgress),需要上传进度时使用原生 XHR 或 axios。 -
v2.0.0 尚未稳定:v2.0.0-alpha 正在开发中,API 可能存在 breaking changes,生产环境建议使用 v1.x 稳定版。
-
社区生态相对集中:主要由 UnJS/Nuxt 团队维护,社区贡献者相比 axios 较少,插件生态不如 axios 丰富。
-
文档相对简略:官方文档(README + Mintlify 站点)覆盖了核心 API,但高级用法和迁移指南不如 axios 详尽。
-
调试支持有限:不像 axios 有 DevTools 插件或浏览器网络面板的深度集成,ofetch 请求在调试工具中的展示依赖浏览器原生网络面板。
-
Node.js 旧版本需要 polyfill:Node.js < 18 依赖
node-fetch-native提供的 polyfill,可能引入边缘兼容问题。
学习资源
官方资源
- GitHub 仓库 — 源码与 API 参考
- UnJS 官方文档 — 包信息与生态定位
- ofetch 文档站 — 特性详解(超时、重试、错误处理等)
Nuxt 集成
- Nuxt useFetch 文档 — Nuxt 3/4 官方 useFetch API
- Nuxt $fetch 文档 — $fetch 工具函数
- When to Use $fetch, useFetch, or useAsyncData — Mastering Nuxt 深度指南
社区与教程
- 如何使用 ofetch:重新定义现代 Web 数据交互的终极指南 — CSDN 中文教程
- API Client Libraries: Axios vs ky vs ofetch in 2026 — PkgPulse 对比指南
- Axios vs. Fetch: Which Fetch Wrapper Should I Choose in 2025? — Dev.to 选型分析
- Hey API — ofetch Client — OpenAPI 代码生成与 ofetch 集成
视频
- Nuxt 3 發送 API 請求資料 — 從 $fetch 與 useAsyncData 到 useFetch — iThelp 中文教程
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