Next.js 13中Fetch请求无法返回Cookie问题咨询
这不是Next.js 13的Bug,而是App Router的组件执行逻辑变化导致的——你当前的组件是服务器组件(App Router默认组件类型),服务器组件中的fetch是在服务器端发起的,接口返回的Set-Cookie头会被服务器接收,但不会自动同步到浏览器的Cookie存储中。而Next.js 12的Pages Router默认是客户端组件,fetch在浏览器端执行,Cookie会直接被浏览器保存。
解决方案1:改为客户端组件(推荐登录场景使用)
在文件顶部添加'use client'指令,让组件在浏览器端执行,这样fetch的credentials: 'include'就能正常让浏览器保存Cookie:
'use client'; import React from 'react' import TodoList from './TodoList' const fetchSingle = async () => { const res = await fetch(`http://localhost:3000/auth/signin`, { credentials: 'include', method: 'POST', headers: { 'Accept': 'application/json, text/plain, */*', 'Content-Type': 'application/json' }, body: JSON.stringify({ email: 'test@gmail.com', password: '12345' }) }) if (!res.ok) { console.error('登录请求失败'); throw new Error('登录失败'); } return res } export default function Todos() { React.useEffect(() => { const handleLogin = async () => { const response = await fetchSingle() console.log(response) } handleLogin() }, []) return ( <div> {/* @ts-ignore */} <TodoList /> </div> ) }
注意:客户端组件不能是async函数,所以要把异步请求放到useEffect中执行。
解决方案2:在服务器组件中手动传递Cookie(仅特殊场景使用)
如果必须在服务器组件处理登录逻辑,可以提取接口返回的Set-Cookie头,手动添加到客户端响应头中,让浏览器接收:
import { headers } from 'next/headers'; import React from 'react' import TodoList from './TodoList' const fetchSingle = async () => { const res = await fetch(`http://localhost:3000/auth/signin`, { credentials: 'include', method: 'POST', headers: { 'Accept': 'application/json, text/plain, */*', 'Content-Type': 'application/json' }, body: JSON.stringify({ email: 'test@gmail.com', password: '12345' }) }) return { response: res, cookies: res.headers.getSetCookie() } } export default async function Todos() { const { response, cookies } = await fetchSingle() const responseHeaders = headers(); cookies.forEach(cookie => { responseHeaders.append('Set-Cookie', cookie); }) console.log(response) return ( <div> {/* @ts-ignore */} <TodoList /> </div> ) }
额外检查项
- 确认API接口的
Set-Cookie头配置:SameSite(跨域场景建议设为None并配合Secure)、Path、Domain等参数需符合浏览器Cookie存储规则; - 检查浏览器隐私设置,是否阻止了第三方Cookie(若API与前端域名不同)。
内容的提问来源于stack exchange,提问作者Firdaus Ismail
相关产品推荐
相关产品推荐

