Next.js App Router服务器组件调用API路由获取Session异常
Next.js + Auth.js 服务器组件调用API路由session为null且部署报错"Headers cannot be modified"的解决方法
问题本质
- 服务器组件中直接传递
headers()返回的Headers对象时,生产环境下Next.js会限制该只读对象的修改操作,导致报错;开发环境限制较宽松所以未触发问题。 - 服务器组件本身运行在服务端,完全没必要通过API路由间接获取Session,直接调用
getServerSession是更高效的方案。
方案一:直接在服务器组件中获取Session(推荐)
服务器组件支持直接调用服务端方法,无需通过API路由中转:
// 服务器组件代码 import { getServerSession } from "next-auth"; import { authOptions } from "@/utils/authOptions"; const ServerComponent = async () => { const session = await getServerSession(authOptions); if (!session) { return <div>未登录,请先登录</div>; } return <div>欢迎回来,{session.user?.name}</div>; }; export default ServerComponent;
方案二:必须调用API路由时的正确传参方式
若业务需求必须调用API路由,不能直接传递原始headers()对象,需创建新Headers实例并复制必要的头信息(比如Auth.js依赖的Cookie):
// 服务器组件中的fetch代码 import { headers } from "next/headers"; const getUser = async () => { const requestHeaders = headers(); // 创建新的Headers对象,仅复制所需的Cookie头 const newHeaders = new Headers(); const cookie = requestHeaders.get("Cookie"); if (cookie) newHeaders.set("Cookie", cookie); // 服务器组件中使用相对路径即可,无需完整域名 const res = await fetch(`/api/example`, { headers: newHeaders, // 若需动态数据,添加cache: 'no-store'避免缓存 cache: "no-store" }); return res.json(); };
报错原因说明
生产环境下,Next.js返回的headers()对象是不可变的只读实例,直接作为fetch的headers参数传递时,fetch底层会尝试修改该对象,触发"Headers cannot be modified"错误;开发环境限制较宽松,因此未暴露该问题。
内容的提问来源于stack exchange,提问作者Panuphong Burakitphachai
相关产品推荐
相关产品推荐

