You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS中RootLayout获取Cookie较Middleware延迟一次刷新的问题

NextJS中Middleware设置Cookie后RootLayout获取旧值的原因分析

我最近在开发NextJS时遇到了一个异常:因为无法从RootLayout组件中获取contextSpec(请求/响应对象),所以我通过Middleware设置Cookie,再结合Next的Cookie库在RootLayout中恢复用户会话。但出现了问题:Middleware设置新Cookie后,RootLayout获取到的是旧版本;删除Cookie后,RootLayout仍能读取到该Cookie。只有刷新页面后两者才同步,RootLayout的Cookie总是滞后一次请求。简化测试后,我在Middleware里设置含随机值的Cookie,RootLayout还是只能拿到上一次的随机值。

相关代码如下:

middleware.ts

export async function middleware(request: NextRequest) {
  const token = { email: Math.random() };

  const response = NextResponse.next();

  response.cookies.set("my_custom_cookie", JSON.stringify(token));

  console.log("EMAIL FROM MIDDLEWARE = ", token.email);

  return response;
}

RootLayout.tsx

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  const cookieStore = cookies();
  const idTokenCookie = cookieStore.get("my_custom_cookie");
  const idToken = idTokenCookie ? JSON.parse(idTokenCookie.value) : null;

  console.log("EMAIL FROM ROOT LAYOUT = ", idToken?.email);

  const user = {
    email: idToken?.email,
  };

  return (
    <html suppressHydrationWarning={true} lang="fr">
      <body className={inter.className}>
        <AuthProvider initialUser={user}>
          {children}
        </AuthProvider>
      </body>
    </html>
  );
}

异常原因

这个问题的核心是Next.js的渲染时序和Cookie传递机制导致的:

  • 服务端渲染时序问题:当请求到达时,Next.js会优先执行RootLayout的服务端渲染逻辑,此时它读取的是请求中携带的原始Cookie(也就是上一次请求留下的旧值)。而Middleware是在RootLayout渲染完成后,才会处理响应并设置新的Cookie到响应头中——这个新Cookie只会在浏览器收到响应后被保存,要等到下一次请求才会被携带到服务器。
  • 客户端导航复用状态:如果是通过next/link进行客户端导航,Next.js会复用现有客户端的状态,RootLayout不会重新执行服务端渲染逻辑,自然也不会读取新的Cookie值,直到页面刷新触发全新的HTTP请求。

简单来说:RootLayout读取的是当前请求的入站Cookie,而Middleware设置的是出站响应Cookie,两者不在同一个请求周期内生效,所以会出现RootLayout的Cookie总是滞后一次请求的现象。

内容的提问来源于stack exchange,提问作者Ludovic Vue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 10:10:06