NextJS App Router中服务端Fetch如何传递浏览器Cookie?
服务端环境与浏览器环境相互独立,默认不会自动携带浏览器的Cookie,需要手动将浏览器Cookie传递给服务端的fetch请求,以下是不同Next.js场景下的实现方案:
1. Pages Router 中的 getServerSideProps 场景
在getServerSideProps中,可以从上下文对象的req.headers.cookie获取浏览器的Cookie字符串,直接添加到fetch请求的headers里:
export async function getServerSideProps(context) { // 提取浏览器请求中的Cookie const browserCookies = context.req.headers.cookie; const tokenCalled4PublicApis = '你的令牌值'; // 根据实际逻辑获取令牌 try { const data = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/${API_ENDPOINTS.HOME}`, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${tokenCalled4PublicApis}`, Accept: 'application/json', 'Cache-Control': 'public, max-age=60, stale-while-revalidate=60', // 手动传递浏览器Cookie Cookie: browserCookies || '' } // 服务端请求无需配置credentials: 'include' }); const result = await data.json(); return { props: { homeData: result } }; } catch (error) { console.error('获取首页数据失败:', error); return { props: { homeData: null } }; } }
2. App Router 中的 Server Component 场景
在App Router的Server Component中,使用Next.js提供的cookies()函数获取Cookie,再传递给fetch请求:
import { cookies } from 'next/headers'; import { API_ENDPOINTS } from '@/constants/api'; export default async function HomePage() { const cookieStore = cookies(); // 将所有Cookie转为字符串格式 const browserCookieString = cookieStore.toString(); const tokenCalled4PublicApis = '你的令牌值'; try { const data = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/${API_ENDPOINTS.HOME}`, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${tokenCalled4PublicApis}`, Accept: 'application/json', 'Cache-Control': 'public, max-age=60, stale-while-revalidate=60', Cookie: browserCookieString } }); const result = await data.json(); return <div>{/* 渲染数据内容 */}</div>; } catch (error) { console.error('获取首页数据失败:', error); return <div>加载失败</div>; } }
3. App Router 中的 Route Handler 场景
在Route Handler中,同样通过cookies()函数获取Cookie,添加到fetch请求头:
import { cookies } from 'next/headers'; import { API_ENDPOINTS } from '@/constants/api'; export async function GET() { const cookieStore = cookies(); const browserCookieString = cookieStore.toString(); const tokenCalled4PublicApis = '你的令牌值'; try { const data = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/${API_ENDPOINTS.HOME}`, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${tokenCalled4PublicApis}`, Accept: 'application/json', 'Cache-Control': 'public, max-age=60, stale-while-revalidate=60', Cookie: browserCookieString } }); const result = await data.json(); return Response.json(result); } catch (error) { console.error('获取首页数据失败:', error); return Response.json({ error: '加载失败' }, { status: 500 }); } }
关键注意事项
- 服务端请求无需配置
credentials: 'include',该配置仅适用于浏览器端fetch请求。 - 若仅需传递特定Cookie(如XSRF-TOKEN),可单独提取:
之后在headers中设置// Pages Router const xsrfToken = context.req.cookies['XSRF-TOKEN']; // App Router const xsrfToken = cookieStore.get('XSRF-TOKEN')?.value;Cookie:XSRF-TOKEN=${xsrfToken}`即可。 - 若API与Next.js应用不在同一域名下,需确保API端配置了允许携带Cookie的跨域响应头,但服务端到服务端的请求不存在跨域问题,内部API调用可忽略此步骤。
内容的提问来源于stack exchange,提问作者Anwar Hossain
相关产品推荐
相关产品推荐

