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
相关产品推荐
相关产品推荐

