Next.js如何实现浏览器关闭清cookie、localStorage但页面跳转时保留
Next.js 浏览器关闭清空存储、站内跳转保留的实现方案
核心原理
Next.js 客户端路由跳转(next/link、useRouter提供的push/replace方法)默认不会触发页面重载,只有整页刷新、站外跳转、关闭浏览器/标签页才会触发页面卸载相关事件。你遇到站内跳转也触发onbeforeunload的问题,大概率是站内跳转使用了原生<a>标签走了整页重载逻辑,可先统一站内跳转方式排查。
推荐使用sessionStorage特性实现需求,比单独依赖onbeforeunload更稳定(onbeforeunload在浏览器强制关闭等场景下不会触发):sessionStorage的生命周期和当前标签页绑定,标签页关闭时自动清空,页面刷新、站内跳转(哪怕是整页重载)都会保留,刚好匹配需求场景。
具体实现代码
在Next.js的全局入口文件_app.tsx/_app.jsx中添加如下逻辑:
import { useEffect } from 'react' import type { AppProps } from 'next/app' export default function App({ Component, pageProps }: AppProps) { useEffect(() => { // 判断当前标签页是否已存在活跃会话标记 const hasActiveSession = sessionStorage.getItem('site_session_alive') if (!hasActiveSession) { // 首次打开标签页/浏览器重启,清空所有存储 localStorage.clear() // 批量清空所有cookie document.cookie.split(';').forEach(cookieItem => { const [cookieName] = cookieItem.trim().split('=') document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;` }) // 打上会话标记,标签页关闭前该标记一直存在 sessionStorage.setItem('site_session_alive', 'true') } // 可选:多标签页兼容逻辑,所有同站标签页都关闭后才清空存储 // 标签页打开时计数+1 const openTabCount = Number(localStorage.getItem('site_open_tab_count') || 0) localStorage.setItem('site_open_tab_count', String(openTabCount + 1)) // 标签页关闭时计数-1 const handleBeforeUnload = () => { const currentCount = Number(localStorage.getItem('site_open_tab_count') || 0) const newCount = Math.max(0, currentCount - 1) localStorage.setItem('site_open_tab_count', String(newCount)) } window.addEventListener('beforeunload', handleBeforeUnload) return () => { window.removeEventListener('beforeunload', handleBeforeUnload) } }, []) return <Component {...pageProps} /> }
逻辑说明
- 只要标签页没有关闭,
sessionStorage中的会话标记就会一直存在,站内任意跳转、页面刷新都不会触发存储清空 - 关闭浏览器/标签页后重新打开站点时,
sessionStorage已被清空,会触发存储清空逻辑,符合需求 - 可选的多标签页计数逻辑,适合需要多标签页共享存储的场景,仅当所有同站标签页都关闭后,下次打开才会清空存储
内容的提问来源于stack exchange,提问作者Usama Tahir
相关产品推荐
相关产品推荐

