原生 fetch 不支持 ssr,因它是浏览器 api,node.js 环境默认未定义;nuxt3 推荐 $fetch + useasyncdata 组合,实现服务端一次请求、自动注水、防重复及客户端复用。

为什么不能直接用原生 fetch 做 SSR 请求?
原生 fetch 是浏览器内置 API,Node.js(包括 Vite、Next、Nuxt 的服务端环境)默认不提供。即使你装了 node-fetch 或启用 globalThis.fetch,也仅解决“能运行”,但无法解决:
– 请求上下文丢失(如 cookies、headers 未透传)
– 服务端与客户端重复请求(hydration 时双端都发)
– 缓存、超时、错误重试等 SSR 场景关键能力缺失
Nuxt3 中推荐方式:用 $fetch + useAsyncData
这是最稳妥的 SSR 数据获取组合:
-
$fetch 是 Nuxt 封装的跨平台 fetch 工具,底层基于
ofetch,在服务端自动走 Node HTTP,在客户端走浏览器 fetch - useAsyncData 负责声明式数据获取 + 自动 SSR 注水(hydration)+ 防重复请求
示例(组件中):
<script setup lang="ts">
const { data, pending, error } = await useAsyncData(
'user-profile',
() => $fetch('/api/user/123')
)
</script>
✅ 服务端执行一次,把结果注入 HTML;
✅ 客户端 hydration 时复用该数据,不再重发;
✅ 支持 loading 状态和错误处理。
SvelteKit 中:用 server load 函数 + 内置 fetch
SvelteKit 的 +page.server.ts 或 +layout.server.ts 中的 fetch 是框架代理过的版本:
- 服务端运行时,它调用 Node.js 的
undici或node-fetch - 客户端运行时(SPA 导航),它退化为浏览器原生
fetch - 自动携带当前请求的 headers(如 cookie),支持相对路径(如
/api/posts)
示例:
// src/routes/+page.server.ts
export async function load({ fetch }) {
const res = await fetch('/api/posts')
const posts = await res.json()
return { posts }
}
✅ 数据只在服务端获取并序列化进页面;
✅ 客户端路由跳转时,可选择是否复用或重新 fetch。
自己封装 SSR fetch?需注意三点
若不用框架,想在 Express / Nest 等中手动发起请求,建议:
- 服务端统一用
undici(Node 官方推荐,性能好、支持 HTTP/2)或node-fetch@3,别用过时的isomorphic-fetch - 手动透传关键 header:如用户 token、cookie,需从 Express
req.headers中提取并注入 fetch options - 避免在 React Server Components(RSC)或 Vue SSR setup 中直接写
await fetch(...)—— 必须配合 suspense 边界或框架的数据获取钩子,否则 hydration 不一致
本质上,SSR 中“fetch 发送数据”不是语法问题,而是上下文治理问题。选对框架封装($fetch / SvelteKit load / Next’s getServerSideProps),比手写 fetch 更关键。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











