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
相关产品推荐
相关产品推荐

