Next.js 14通用Cookie获取函数问题:兼容SSR与客户端组件
你的代码核心问题是导入了仅能在服务器环境运行的next/headers模块——这个模块的cookies() API只能在服务器组件、API路由、Server Actions等服务器上下文使用,客户端组件直接导入会触发运行时错误,因为客户端没有对应的运行时环境。
下面是两种可落地的修复方案,均能实现跨SSR/客户端组件的通用Cookie获取:
方案一:同步函数(无需异步)
通过条件加载服务器端依赖,确保客户端不会打包服务器端专属代码:
import Cookies from 'js-cookie'; export const getCookie = (cookieName: string): string | undefined => { // 服务器端环境:仅在此分支加载并调用服务器端Cookie API if (typeof window === 'undefined') { const { cookies } = require('next/headers'); const cookie = cookies().get(cookieName); return cookie?.value; } // 客户端环境:使用js-cookie读取浏览器Cookie else { return Cookies.get(cookieName); } };
说明:
- 客户端代码不会执行
typeof window === 'undefined'分支,因此Webpack不会把next/headers打包到客户端 bundle 中,彻底避免报错。 - 移除了原代码中导入的服务器端专属
RequestCookie类型,若需要类型支持,可在服务器端分支单独定义或用泛型兼容。
方案二:基于server-only的类型安全方案
这个方案更贴合Next.js最佳实践,通过server-only包强制隔离服务器端代码,防止意外泄露到客户端:
- 先安装依赖:
npm install server-only
- 创建服务器端专属Cookie工具文件(比如
src/utils/server-cookies.ts):
import 'server-only'; import { cookies } from 'next/headers'; import type { RequestCookie } from 'next/dist/compiled/@edge-runtime/cookies'; export const getServerCookie = (cookieName: string): string | undefined => { const cookie: RequestCookie | undefined = cookies().get(cookieName); return cookie?.value; };
- 编写通用Cookie获取函数:
import Cookies from 'js-cookie'; export const getCookie = async (cookieName: string): Promise<string | undefined> => { if (typeof window === 'undefined') { // 动态导入服务器端专属函数,确保客户端不加载 const { getServerCookie } = await import('./server-cookies'); return getServerCookie(cookieName); } else { return Cookies.get(cookieName); } };
说明:
server-only包会在构建阶段检查,若服务器端代码被意外导入到客户端,会直接抛出错误,提前规避风险。- 此方案为异步函数,适合在组件的
useEffect、Server Actions或异步组件中使用。
额外注意事项
- 在客户端组件中使用该函数时,务必确保组件顶部添加
'use client'指令,否则会触发服务器端渲染逻辑。 - 敏感Cookie(如认证令牌)建议仅在服务器端读取,避免暴露到客户端。
内容的提问来源于stack exchange,提问作者CzechCoder
相关产品推荐
相关产品推荐

