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

Next.js中如何在_app.js内获取cookie,返回undefined如何解决

问题根本原因

Next.js Pages Router 下的自定义 _app.js 不支持 getServerSideProps 方法,该方法仅能在页面级组件(也就是 pages 目录下的路由文件)中使用,这就是你在 index.js 中逻辑正常、在 _app.js 中返回 undefined 的核心原因。
另外你当前的 _app.js 存在语法问题:return 返回的多个同级组件没有根标签包裹,需要用 React Fragment(<></>)或者公共父元素包裹才能正常运行。

官方推荐替代方案(无需使用不推荐的 getInitialProps)

方案1:客户端直接读取Cookie(适合无SSR/SSG场景)

如果 Navbar 不需要服务端渲染 Token 相关的内容,直接在客户端读取 Cookie 是最简单的方案:

  • 安装 Cookie 操作库:npm install js-cookie
  • 修改 Navbar 组件直接读取 Token:
import Cookies from 'js-cookie'
const Navbar = () => {
  const token = Cookies.get('token')
  // 原有业务逻辑
}

不想引入第三方库也可以直接用原生JS解析document.cookie获取值。

方案2:使用Middleware全局注入(适合全场景,Next.js 12+官方推荐)

在项目根目录(和pages目录同级)新建middleware.js,可以在请求到达页面前全局处理Cookie,把Token传递给后续逻辑:

import { NextResponse } from 'next/server'

export function middleware(request) {
  const token = request.cookies.get('token')?.value
  // 把Token放到自定义请求头,方便页面的getServerSideProps读取
  const requestHeaders = new Headers(request.headers)
  requestHeaders.set('x-user-token', token || '')

  return NextResponse.next({
    request: {
      headers: requestHeaders,
    },
  })
}

// 配置匹配所有页面路由
export const config = {
  matcher: '/:path*',
}

之后在任意页面的getServerSideProps中读取这个自定义头,把Token放到pageProps里,_app.js直接从pageProps取值即可:

// 调整后的_app.js代码
import "tailwindcss/tailwind.css";
import Navbar from "../components/Navbar.js"

function MyApp({ Component, pageProps }) {
  return (
    <>
      <Navbar token={pageProps.token} />
      <Component {...pageProps} />
    </>
  )
}

export default MyApp;
// 页面级getServerSideProps示例
export const getServerSideProps = ({ req }) => {
  return {
    props: {
      token: req.headers['x-user-token'] || undefined
    }
  }
}

方案3:封装高阶组件统一添加getServerSideProps

如果项目所有页面都需要SSR,可以封装高阶组件,给所有页面统一加上注入Token的逻辑,避免重复代码:

// utils/withAuth.js
export const withAuth = (getServerSideProps) => {
  return async (ctx) => {
    const token = ctx.req.cookies.token
    const originRes = await getServerSideProps?.(ctx) || { props: {} }
    return {
      ...originRes,
      props: {
        ...originRes.props,
        token
      }
    }
  }
}

页面使用时直接包裹原有逻辑即可:

export const getServerSideProps = withAuth(async (ctx) => {
  // 页面原有getServerSideProps逻辑
  return { props: {} }
})

内容的提问来源于stack exchange,提问作者Shahab Athar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 09:45:04