Next.js 技术总结:Server Action vs Route Handler? client Fetch vs server Fetch?

一、原生Client Fetch vs Server Fetch 的差异

对比点Client Fetch(浏览器)Server Fetch(服务端)
🔐 Cookie 携带方式

理论:默认自动携带(同源),跨域需 credentials: 'include'

实际:same-origin 使用 credentials: 'include 

<理由详见 Token文章>

理论:❌ 不自动携带,必须手动将 Cookie 放入 headers

实际:语义不正确,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:携带什么? ❌ 没有

 

posted @ 2025-07-03 02:19  PEAR2020  阅读(16)  评论(0)    收藏  举报