NextJS无法从Golang Echo后端设置Cookie问题求助(App Router场景)
问题情况
我遇到NextJS无法接收Golang Echo后端设置的Cookie的问题,该接口在Postman、React、Svelte中都能正常设置Cookie,但在NextJS里完全没效果,浏览器控制台和终端也无报错。同时需要适用于App Router的Cookie操作方案(类似原getServerSideProps的功能)。
相关代码
NextJS前端代码
async function getData() { const res = await fetch('http://localhost:3001/', { credentials: 'include' }) if (!res.ok) { throw new Error('Failed to fetch') } return res.json() } export default async function Page() { const data = await getData() return <div>{data.message}</div> }
Golang Echo后端代码
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins: []string{"*"}, AllowHeaders: []string{"*"}, AllowCredentials: true, })) e.GET("/", func(c echo.Context) error { cookie := new(http.Cookie) cookie.Name = "name" cookie.Value = "value" cookie.MaxAge = int(time.Now().AddDate(0, 0, 7).Unix()) cookie.Path = "/" c.SetCookie(cookie) return c.JSON(http.StatusOK, echo.Map{"message": "Hello, World!"}) })
package.json依赖
"next": "latest", "react": "latest", "react-dom": "latest"
问题原因及修复
1. 后端Cookie配置错误
- MaxAge参数错误:原代码中
cookie.MaxAge = int(time.Now().AddDate(0, 0, 7).Unix())是错误的,MaxAge的单位是秒,应该设置为7天的总秒数7*24*60*60,而不是未来时间的Unix时间戳。 - CORS配置冲突:当
AllowCredentials: true时,AllowOrigins不能使用通配符*,必须指定具体的NextJS地址(如http://localhost:3000)。
2. NextJS服务器组件的fetch特性
原代码中的Page是App Router的服务器组件,fetch默认在服务器端执行,服务器端的fetch不会自动将Cookie同步到浏览器客户端。需要改为客户端组件执行fetch,或在服务器端转发Cookie头到客户端。
修正后的代码
修正后的Golang Echo后端代码
import ( "net/http" "time" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" ) func main() { e := echo.New() e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins: []string{"http://localhost:3000"}, // 指定NextJS的运行地址 AllowHeaders: []string{"*"}, AllowCredentials: true, })) e.GET("/", func(c echo.Context) error { cookie := new(http.Cookie) cookie.Name = "name" cookie.Value = "value" cookie.MaxAge = 7*24*60*60 // 7天的秒数 cookie.Path = "/" cookie.HttpOnly = true // 可选,提升Cookie安全性 cookie.SameSite = http.SameSiteLaxMode // 跨域场景建议设置为Lax或None c.SetCookie(cookie) return c.JSON(http.StatusOK, echo.Map{"message": "Hello, World!"}) }) e.Start(":3001") }
NextJS解决方案
方案1:客户端组件执行fetch(让Cookie在浏览器生效)
将Page改为客户端组件,添加'use client'指令,在客户端发起请求:
'use client' import { useState, useEffect } from 'react' async function getData() { const res = await fetch('http://localhost:3001/', { credentials: 'include' }) if (!res.ok) { throw new Error('Failed to fetch') } return res.json() } export default function Page() { const [data, setData] = useState(null) const [error, setError] = useState(null) useEffect(() => { getData().then(setData).catch(setError) }, []) if (error) return <div>加载失败</div> if (!data) return <div>加载中...</div> return <div>{data.message}</div> }
方案2:App Router中服务器端操作Cookie(替代getServerSideProps)
在App Router的服务器组件或Route Handler中,使用cookies()函数实现Cookie的读写:
服务器组件中操作Cookie
import { cookies } from 'next/headers' export default async function Page() { // 读取Cookie const cookieStore = cookies() const nameCookie = cookieStore.get('name') // 从后端获取数据并转发Set-Cookie头到客户端 const res = await fetch('http://localhost:3001/', { credentials: 'include' }) const data = await res.json() return ( <> <div>{data.message}</div> {nameCookie && <div>当前Cookie值:{nameCookie.value}</div>} </> ) }
Route Handler中操作Cookie
import { cookies } from 'next/headers' import { NextResponse } from 'next/server' export async function GET() { // 设置Cookie cookies().set({ name: 'test', value: 'value', maxAge: 60 * 60 * 24 * 7, // 7天 path: '/', httpOnly: true, sameSite: 'lax', }) // 读取Cookie const testCookie = cookies().get('test') return NextResponse.json({ message: 'Cookie已设置', cookieValue: testCookie?.value }) }
内容的提问来源于stack exchange,提问作者dopesoul
相关产品推荐
相关产品推荐

