Next.js 13 如何仅服务端导入next/headers?解决客户端调用报错
问题分析
你遇到的报错核心原因是:next/headers 中的 cookies API 仅能在服务端环境(Server Components、Server Actions、API 路由等)使用,而你的代码在客户端组件中直接导入了这个模块,导致客户端打包时触发了环境不兼容的错误。同时原代码里的环境判断注释写反了:typeof window === "undefined" 对应的是服务端环境,不是客户端。
解决方案
下面提供两种可行的实现方式,都能做到仅在服务端导入 next/headers:
方案一:动态导入+条件分支处理
在服务端逻辑分支内动态导入 cookies,确保客户端不会加载该模块:
import clientCookies from "js-cookie"; const myFetch = async (...args) => { let token; if (typeof window !== "undefined") { // 客户端环境:读取浏览器 Cookie token = clientCookies.get("authToken"); } else { // 服务端环境:动态导入并读取服务端 Cookie const { cookies } = await import("next/headers"); const serverCookies = cookies(); token = serverCookies.get("authToken")?.value; } // 合并原有请求头,避免覆盖用户传入的其他头信息 args[1] = args[1] || {}; args[1].headers = { ...args[1].headers, Authorization: token ? `bearer ${token}` : undefined, }; const res = await fetch(...args); const data = await res.json(); return data; }; export default myFetch;
方案二:拆分客户端/服务端专用函数
将客户端和服务端的逻辑完全分离,分别导出后根据环境选择使用:
// client-fetch.js(仅客户端使用) import clientCookies from "js-cookie"; export const clientFetch = async (...args) => { const token = clientCookies.get("authToken"); args[1] = args[1] || {}; args[1].headers = { ...args[1].headers, Authorization: token ? `bearer ${token}` : undefined, }; const res = await fetch(...args); return res.json(); };
// server-fetch.js(仅服务端使用) import { cookies } from "next/headers"; export const serverFetch = async (...args) => { const serverCookies = cookies(); const token = serverCookies.get("authToken")?.value; args[1] = args[1] || {}; args[1].headers = { ...args[1].headers, Authorization: token ? `bearer ${token}` : undefined, }; const res = await fetch(...args); return res.json(); };
// index.js(统一导出入口) let myFetch; if (typeof window !== "undefined") { myFetch = (await import("./client-fetch.js")).clientFetch; } else { myFetch = (await import("./server-fetch.js")).serverFetch; } export default myFetch;
额外注意事项
- 处理
token不存在的情况,避免生成bearer undefined这种无效的授权头 - 不要直接覆盖
args[1].headers,通过扩展运算符合并原有头信息,防止丢失用户传入的其他请求头 - 确保环境判断逻辑正确:
typeof window !== "undefined"才是客户端环境
内容的提问来源于stack exchange,提问作者cherakkal_a
相关产品推荐
相关产品推荐

