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

Next.js 14页面跳转无法获取最新Cookie,需硬刷新问题求助

解决Next.js 14跳转后获取最新Cookie的问题

核心原因

Next.js 14 App Router默认对页面做静态优化,如果/booking页面被静态缓存,会复用构建时或首次请求的Cookie数据,导致跳转后无法获取最新值。另外客户端跳转时,若未触发页面数据刷新,也会读取旧的Cookie缓存。

解决方案

1. 强制/booking页面动态渲染

在/booking的页面组件中添加动态渲染配置,让Next.js每次请求都重新获取最新Cookie:

// app/booking/page.tsx
export const dynamic = 'force-dynamic'; // 禁用静态缓存,强制每次请求都重新渲染

import { cookies } from 'next/headers';
import { decryptEvent } from '@/lib/encryption'; // 你的解密函数

async function BookingPage() {
  const cookieStore = await cookies();
  const encryptedEvent = cookieStore.get('encryptedEvent')?.value;
  
  if (!encryptedEvent) {
    return <div>No booking data found</div>;
  }
  
  const eventData = decryptEvent(encryptedEvent);
  return (
    <div>
      <h1>Booking for: {eventData.title}</h1>
      {/* 其他预订表单内容 */}
    </div>
  );
}

export default BookingPage;

2. 客户端跳转后强制刷新数据

如果/events页面的Book按钮是客户端组件,跳转时调用router.refresh()强制目标页面更新:

// app/events/components/EventCard.tsx
'use client';

import { useRouter } from 'next/navigation';
import { setCookie } from 'cookies-next'; // 或自定义Cookie操作逻辑
import { encryptEvent } from '@/lib/encryption'; // 你的加密函数

export default function EventCard({ event }) {
  const router = useRouter();

  const handleBook = () => {
    const encryptedData = encryptEvent(event);
    // 存入Cookie
    setCookie('encryptedEvent', encryptedData, {
      path: '/',
      httpOnly: false, // 若需客户端读取则设为false,服务器端读取可设为true
      secure: process.env.NODE_ENV === 'production',
    });
    // 跳转并强制刷新页面
    router.push('/booking');
    router.refresh();
  };

  return (
    <div className="event-card">
      <h3>{event.title}</h3>
      <button onClick={handleBook}>Book Now</button>
    </div>
  );
}

3. 客户端组件监听路由变化重新获取Cookie

如果/booking是客户端组件,监听路由完成事件,每次进入页面都重新读取最新Cookie:

// app/booking/page.tsx
'use client';

import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import { getCookie } from 'cookies-next';
import { decryptEvent } from '@/lib/encryption';

export default function BookingPage() {
  const router = useRouter();
  const [eventData, setEventData] = useState(null);

  const fetchLatestBookingData = () => {
    const encrypted = getCookie('encryptedEvent');
    if (encrypted) {
      setEventData(decryptEvent(encrypted));
    }
  };

  useEffect(() => {
    // 首次加载获取数据
    fetchLatestBookingData();
    // 监听路由变化,每次进入页面都重新获取
    const unsubscribe = router.events.on('routeChangeComplete', fetchLatestBookingData);
    return () => unsubscribe();
  }, [router]);

  if (!eventData) {
    return <div>Loading booking data...</div>;
  }

  return (
    <div>
      <h1>Booking Details</h1>
      <p>Event: {eventData.title}</p>
      <p>Date: {eventData.date}</p>
    </div>
  );
}

4. 替代方案:用URL参数传递加密ID(更可靠)

避免依赖Cookie传递数据,改为传递加密后的活动ID,在/booking页面从服务器端拉取最新数据:

// app/events/components/EventCard.tsx
'use client';

import { useRouter } from 'next/navigation';
import { encryptId } from '@/lib/encryption';

export default function EventCard({ event }) {
  const router = useRouter();

  const handleBook = () => {
    const encryptedId = encryptId(event.id);
    router.push(`/booking?eventId=${encryptedId}`);
  };

  return <button onClick={handleBook}>Book Now</button>;
}
// app/booking/page.tsx
import { decryptId } from '@/lib/encryption';
import { getEventById } from '@/lib/data'; // 你的数据获取函数

async function BookingPage({ searchParams }) {
  const eventId = decryptId(searchParams.eventId);
  const event = await getEventById(eventId);

  if (!event) {
    return <div>Invalid booking request</div>;
  }

  return (
    <div>
      <h1>Booking for {event.title}</h1>
      {/* 预订表单 */}
    </div>
  );
}

export default BookingPage;

内容的提问来源于stack exchange,提问作者nehat khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 06:32:41