Next.js 14页面间传递数据:router.push传响应数据报错求解决
Next.js 14 页面间传递响应数据的解决方案
你的代码里router.push报错的核心原因是直接将完整的responseData对象传给query参数——Next.js的query要求是可序列化的简单键值对(字符串/数字类型),复杂对象无法被正确解析,因此会触发错误;同时这种方式还会把敏感数据暴露在URL中,存在安全风险。
以下是几种适配Next.js 14的可行解决方案,可根据数据敏感性和业务场景选择:
方案1:利用LocalStorage/SessionStorage(适合非敏感数据)
你已经在登录成功后将token和username存入localStorage,如果responseData还有其他需要传递的非敏感数据,可以直接扩展存储逻辑,目标页面从localStorage读取即可:
// 登录页面:存储完整响应数据 localStorage.setItem('userData', JSON.stringify(responseData)); // 目标页面(客户端组件)读取数据 'use client'; import { useEffect, useState } from 'react'; export default function Home() { const [userData, setUserData] = useState(null); useEffect(() => { const storedData = localStorage.getItem('userData'); if (storedData) { setUserData(JSON.parse(storedData)); } }, []); return <div>欢迎回来,{userData?.username}</div>; }
方案2:使用React Context(全局状态管理)
通过创建全局Context,将响应数据存入状态,目标页面直接从Context中读取,适合需要在多个页面共享用户数据的场景:
1. 创建AuthContext
// app/context/AuthContext.tsx 'use client'; import { createContext, useContext, useState, ReactNode } from 'react'; type UserData = { token: string; username: string; // 其他字段根据responseData定义 }; type AuthContextType = { userData: UserData | null; setUserData: (data: UserData) => void; }; const AuthContext = createContext<AuthContextType | undefined>(undefined); export function AuthProvider({ children }: { children: ReactNode }) { const [userData, setUserData] = useState<UserData | null>(null); return ( <AuthContext.Provider value={{ userData, setUserData }}> {children} </AuthContext.Provider> ); } export function useAuth() { const context = useContext(AuthContext); if (!context) { throw new Error('useAuth 必须在 AuthProvider 内部使用'); } return context; }
2. 在根布局中包裹Provider
// app/layout.tsx import { AuthProvider } from './context/AuthContext'; export default function RootLayout({ children }: { children: ReactNode }) { return ( <html lang="it"> <body> <AuthProvider>{children}</AuthProvider> </body> </html> ); }
3. 登录页面更新Context
// 登录页面 const { setUserData } = useAuth(); // 登录成功后 setUserData(responseData); router.push('/');
4. 目标页面读取数据
// 目标页面(客户端组件) 'use client'; import { useAuth } from '@/app/context/AuthContext'; export default function Home() { const { userData } = useAuth(); return <div>欢迎回来,{userData?.username}</div>; }
方案3:使用SearchParams(仅适合非敏感、简单数据)
如果仅需传递少量非敏感字段(如用户名),可以将字段拆解为query参数,目标页面通过useSearchParams读取:
// 登录页面 router.push({ pathname: '/', query: { username: responseData.username // 只传必要的非敏感字段 } });
// 目标页面(客户端组件) 'use client'; import { useSearchParams } from 'next/navigation'; export default function Home() { const searchParams = useSearchParams(); const username = searchParams.get('username'); return <div>欢迎回来,{username}</div>; }
⚠️ 注意:绝对不要通过URL传递token等敏感数据,会导致数据泄露。
方案4:结合Cookie与Server Component(适合敏感数据)
对于token这类敏感数据,推荐后端在登录接口返回时设置HttpOnly Cookie,前端无需手动存储,目标页面(Server Component)可直接从请求Cookie中读取并获取用户信息:
// 目标Server Component import { cookies } from 'next/headers'; async function fetchUserInfo(token: string) { const res = await fetch('http://localhost:8080/api/user/info', { headers: { Authorization: `Bearer ${token}` } }); return res.json(); } export default async function Home() { const cookieStore = cookies(); const accessToken = cookieStore.get('accessToken')?.value; const userData = accessToken ? await fetchUserInfo(accessToken) : null; return <div>欢迎回来,{userData?.username}</div>; }
内容的提问来源于stack exchange,提问作者Lorenzo Ferrara
相关产品推荐
相关产品推荐

