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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 13:18:28