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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 09:30:41