如何在Next.js中检测来源页面URL,避免重复重定向
问题场景与需求
我在某个页面中使用router.push('destination-url')将用户重定向到外部链接。现在需要实现:
- 检查用户是否是从之前重定向到的外部页面点击返回回到当前页面
- 如果用户是从外部链接返回的,禁止再次访问当前页面(避免重复重定向到同一个外部目标)
- 换个说法:只有当用户来自特定内部页面时,才允许将其重定向到外部链接
用户当前代码:
useEffect(() => { if (window) { if (router.isReady) { // --- HERE I NEED TO CHECK IF USER CLICKED BACK FROM THE EXTERNAL URL THAT I ALREADY REDIRECTED THEM TO --- getLinkAddress({id: router.query.id, price: router.query.price}).then((r1) => { if (r1.link_address) { setFound(true); router.push(r1.link_address).then(); } else { setFound(false); setTimeout(() => { router.back(); }, 3000); } }); } } return () => { }; }, [router.query]);
解决方案
下面提供两种实用的实现方式,可根据场景选择:
方法一:通过document.referrer判断来源
利用浏览器提供的document.referrer获取上一页的URL,判断是否来自外部链接:
useEffect(() => { if (window && router.isReady) { // 获取上一页的来源地址 const referrer = document.referrer; // 定义自己网站的域名(允许的内部页面域名) const internalDomain = window.location.origin; // 判断是否来自外部链接:referrer存在且不是自己的域名 const isFromExternal = referrer && !referrer.startsWith(internalDomain); // 如果是从外部返回,直接跳回之前的内部页面 if (isFromExternal) { router.back(); return; } getLinkAddress({id: router.query.id, price: router.query.price}).then((r1) => { if (r1.link_address) { setFound(true); router.push(r1.link_address).then(); } else { setFound(false); setTimeout(() => { router.back(); }, 3000); } }); } return () => {}; }, [router.query]);
方法二:用sessionStorage标记重定向状态
在跳转到外部链接前设置标记,返回时检查标记判断是否来自外部:
useEffect(() => { if (window && router.isReady) { // 检查是否存在"已跳转到外部"的标记 const hasRedirected = sessionStorage.getItem('redirectedToExternal'); if (hasRedirected) { // 清除标记,避免重复触发判断 sessionStorage.removeItem('redirectedToExternal'); // 跳回之前的内部页面 router.back(); return; } getLinkAddress({id: router.query.id, price: router.query.price}).then((r1) => { if (r1.link_address) { setFound(true); // 设置标记,记录即将跳转到外部 sessionStorage.setItem('redirectedToExternal', 'true'); router.push(r1.link_address).then(); } else { setFound(false); setTimeout(() => { router.back(); }, 3000); } }); } return () => {}; }, [router.query]);
两种方法对比
document.referrer方法:无需额外存储,但部分浏览器隐私策略可能会限制referrer的获取,或者用户直接输入URL时referrer为空。sessionStorage方法:可靠性更高,不受referrer限制,但标记会在浏览器关闭后自动清除,适合会话内的判断。
内容的提问来源于stack exchange,提问作者Hooman Limouee
相关产品推荐
相关产品推荐

