NextJS:如何将_app.js的getInitialProps数据传递给页面getServerSideProps
解决Next.js中_app.getInitialProps数据共享给页面getServerSideProps的问题
问题根源
首次访问时,_app.js的getInitialProps与页面的getServerSideProps属于同一次服务器请求:
js-cookie是客户端库,在服务器端执行时设置的cookie不会同步到当前请求的req.cookies中,只有浏览器收到响应后,下次请求才会携带该cookie;- 因此首次访问时页面的
getServerSideProps无法通过req.cookies拿到刚设置的数据。
解决方案:同请求内挂载数据+持久化cookie
通过在服务器端将数据挂载到req对象实现同请求内的即时共享,同时设置响应头cookie保证后续请求能获取数据。
修改_app.js
import cookies from 'js-cookie'; const App = ({ Component, pageProps }) => { return <Component {...pageProps} />; }; App.getInitialProps = async ({ ctx }) => { const { req, res } = ctx; const data = await fetchSomeData(); if (req) { // 服务器端:将数据挂载到req对象,供同请求内的getServerSideProps直接读取 req.myData = data; // 设置响应头cookie,供后续请求使用(需将对象转为字符串) const cookieValue = encodeURIComponent(JSON.stringify(data)); res.setHeader('Set-Cookie', `myData=${cookieValue}; Path=/; HttpOnly; SameSite=Lax`); } else { // 客户端环境用js-cookie设置 cookies.set('myData', data); } return { pageProps: { data } }; }; export default App;
修改页面的getServerSideProps
// [...products].js export async function getServerSideProps({ req }) { // 优先读取同请求内挂载的数据,无则从cookie解析(适配后续请求) let myData = req.myData; if (!myData && req.cookies.myData) { myData = JSON.parse(decodeURIComponent(req.cookies.myData)); } const ids = myData?.ids; // 根据你的数据结构调整 const products = getProductByIds(ids); return { props: { products, }, }; }
注意事项
- 若数据是复杂对象,需用
JSON.stringify转成字符串存储到cookie,读取时用JSON.parse解析; HttpOnly属性可防止XSS攻击,若客户端无需读取该cookie建议保留;若客户端需要读取,移除HttpOnly即可;- 用
encodeURIComponent/decodeURIComponent处理特殊字符,避免cookie存储异常。
内容的提问来源于stack exchange,提问作者Amarjit yadav
相关产品推荐
相关产品推荐

