Next.js中getInitialProps获取localStorage返回undefined求助
解决Next.js中getInitialProps访问localStorage返回undefined的问题
嘿,这个问题我碰到好多次了——你在getInitialProps里调用localStorage返回undefined,核心原因其实很直白:getInitialProps会在服务器端和客户端两端执行,而服务器环境根本没有localStorage这个浏览器专属的API!
当页面第一次被请求时,Next.js会在服务器端完成渲染,这时候代码里的localStorage.getItem('auth')就相当于在没有window对象的环境里调用浏览器API,自然返回undefined。
解决方案1:判断运行环境,仅在客户端读取localStorage
如果你的页面不需要服务器端渲染时就拿到token(比如只在客户端交互后才请求数据),可以先判断当前是否在客户端环境,再读取localStorage:
Dashboard.getInitialProps = async () => { let token = null; // 只有在客户端环境(存在window对象)时才读取localStorage if (typeof window !== 'undefined') { token = localStorage.getItem('auth'); } // 没有token时做降级处理,比如返回空数据或跳转到登录页 if (!token) { return { page: null }; } const res = await fetch(`${process.env.API_URL}/pages/about`, { headers: { 'Authorization': token } }); const data = await res.json(); return { page: data }; };
解决方案2:改用Cookie存储token(支持服务器端读取)
如果你的页面需要在服务器端渲染时就携带token请求数据,那localStorage肯定不行——因为服务器端拿不到客户端的localStorage。这时候建议把token存在Cookie里,Cookie会在每次请求时自动发送给服务器,服务器端可以通过请求头解析拿到。
第一步:客户端登录成功后把token存到Cookie
// 登录成功后,把token存入Cookie(也可以用js-cookie库简化操作) document.cookie = `auth=${yourToken}; path=/; max-age=86400; SameSite=Lax`; // max-age设置过期时间(这里是1天),SameSite提升安全性
第二步:在getInitialProps中兼容客户端和服务器端读取token
// 可以用js-cookie库来解析Cookie,先安装:npm install js-cookie import cookie from 'js-cookie'; Dashboard.getInitialProps = async ({ req }) => { let token = null; // 服务器端:从请求头的Cookie中解析token if (req) { const cookieStr = req.headers.cookie; if (cookieStr) { const cookies = cookie.parse(cookieStr); token = cookies.auth; } } else { // 客户端:优先从localStorage拿,或者直接从Cookie拿 token = localStorage.getItem('auth') || cookie.get('auth'); } // 没有token时可以直接跳转到登录页 if (!token) { return { redirect: { destination: '/login', permanent: false } }; } const res = await fetch(`${process.env.API_URL}/pages/about`, { headers: { 'Authorization': token } }); const data = await res.json(); return { page: data }; };
额外建议:使用Next.js新的数据获取方法
如果你用的是Next.js 9.3及以上版本,官方更推荐用getServerSideProps(服务器端渲染)或getStaticProps(静态生成)代替getInitialProps,它们的职责更清晰,也更容易处理这类环境差异问题。比如用getServerSideProps的示例:
import cookie from 'js-cookie'; export async function getServerSideProps({ req }) { let token = null; if (req.headers.cookie) { const cookies = cookie.parse(req.headers.cookie); token = cookies.auth; } // 无token时直接重定向到登录页 if (!token) { return { redirect: { destination: '/login', permanent: false } }; } const res = await fetch(`${process.env.API_URL}/pages/about`, { headers: { 'Authorization': token } }); const data = await res.json(); return { props: { page: data } }; }
内容的提问来源于stack exchange,提问作者Sonjoy Datta
相关产品推荐
相关产品推荐

