Next.js 技术总结:Server Action vs Route Handler? client Fetch vs server Fetch?
一、原生Client Fetch vs Server Fetch 的差异
| 对比点 | Client Fetch(浏览器) | Server Fetch(服务端) |
|---|---|---|
| 🔐 Cookie 携带方式 |
理论:默认自动携带(同源),跨域需 实际:same-origin 使用 <理由详见 Token文章> |
理论:❌ 不自动携带,必须手动将 实际:语义不正确,server fetch只用Authorization <理由详见 Token文章> |
| 🌐 路径补全 | ✅ 支持相对路径,会自动补全为当前 origin | ❌ 不支持相对路径,必须写完整绝对路径(带协议和域名) |
| 🎯 运行上下文 | 有页面上下文(host、用户、location) | 没有上下文,必须开发者显式提供; fetch是纯函数环境 |
| ⚙️ 可设置缓存行为 | cache: 'force-cache' | 'no-store' | ❌ no cache |
二、NextJS fetch 增强点:只增强server fetch!
Server fetch 增强点
1. 相对路径自动补全,执行route handler, 不发送真实网络请求!
2. next.revalidate 是服务端编译阶段用于构建 ISR 缓存依赖图 的指令
next: { revalidate: 60, // ISR 缓存秒数 tags: ['product'], // ISR 依赖标记 }
3. 控制 SSR cache
cache: 'no-store'
三、Server Action vs Route Handler
✅ Route Handler (/app/api/xxx/route.ts)
- 更适合做 查询类 GET 请求,比如获取当前登录用户、拉取商品列表;
- 可以配置 缓存机制(如
revalidate、ISR、SWR 等),具有高可控性;
✅ Server Action (action.ts)
- 更适合做 带副作用的修改行为,比如:提交表单、写数据库、修改状态;
- ❌ 不支持缓存。如果强行使用页配置const revalidate = 30,该缓存设置会自动作废。
必须运行在:
-
Server Component 内部直接调用;
-
或
<form action={yourAction}>中由浏览器发起提交;
| 使用场景 | 推荐方案 |
|---|---|
| 获取登录状态 / 查询商品 | ✅ Route Handler + fetch(可缓存、可重用) |
| 用户注册 / 提交订单 / 表单行为 | ✅ Server Action(组件内直接调用) |
| 通用 API 服务(第三方调用) | ✅ Route Handler |
| 后台管理系统的按钮操作 | ✅ Client fetch + Route Handler 或 <form action={} + Server Action |
总结
server action
来源于:RSC or client Comp <form> submittion
那么是否可以来源于Route handler? 答:build-time!需要编译!
适用于:执行“副作用”行为。 不可以缓存!
是否能await cookie or headers? ❌ 由于是直接调用方法而来,不会携带,所以不能
route handler
来源于:client or server Fetch
适用于:查询方法
假网络通信, 所以可以使用await cookie(),等同于req.cookie接受传递的cookie
本质:cookies() 是对 req.headers.get('cookie') 的进一步封装
第一个参数是req,第二个参数可以是{ params } : { params: { tenantId: string } } 获得动态参数
SSR: RSC
来源于: hard nav or soft nav
接受hard nav/ soft nav自动携带的 cookie、headers: await cookie/headers
用于查询注入client comp,
1. 选择server fetch+单条revalidate:
坏处:额外await cookie,塞入headers传递
好处:控制细粒度revalidate
2.选择页面级revalidate+async function
好处:直接await cookies() 直接拿来就用,✅ 更适合大多数场景
nextjs-client fetch
相对路径自动补全
cookie:credentials:'include'用于同源
cache: 可;默认是 no-store
ISR: ❌ 比如客户端发起client fetch,是否能每隔30秒重新发起,
不行,因为是ISR是编译行为,
Client fetch 是运行时行为,不受 ISR 控制。
token:同源用HttpOnly cookie+credentials,跨源用headers:Authentication: Bearer Token
nextjs-server fetch
相对路径自动补全
cache: 可以cache
ISR: revalidate可多组件复用缓存; 注意使用的时候搭配上page revalidate是最佳实践
cookie:headers中设置cookie。
token:同源用cookie,跨源用headers:Authentication
hard nav
来源于:刷新 or URL address input
cookie:自动携带same site cookie; 只要不是 SameSite=Strict
headers:携带来自浏览器 or mobile or IP 包括 UA、Accept-Language、Referer 等
soft nav
来源于: <Link> or useRouter().push or redirect
cookie:自动携带same site cookie
headers:携带什么? ❌ 没有

浙公网安备 33010602011771号