是否可以检测用户是否在新选项卡中打开了链接?

Posted

技术标签:

【中文标题】是否可以检测用户是否在新选项卡中打开了链接?【英文标题】:Is it possible to detect if a user has opened a link in a new tab? 【发布时间】:2010-10-25 09:41:44 【问题描述】:

如果用户在您的网站上并在新选项卡中打开另一个链接(也指向您的网站),是否可以将其与仅正常单击该链接的用户区分开来?这可以在 javascript 中,在服务器上,等等。

我猜答案是你不能这样做,但我想仔细检查一下。

【问题讨论】:

【参考方案1】:

你可以这样做:

if (history.length == 1)   // Um, needs to be 0 for IE, 1 for Firefox
    // This is a new window or a new tab.

history.length 可能还有其他方式成为1,但我不知道它们可能是什么。

【讨论】:

@Jason:当我尝试查看 history.previous 时,我在 Firefox 中遇到权限错误。 @RichieHindle:嗯……我正试图把手指放在它上面……但是是的……这就是我烂的原因…… 您也可以使用Visibility API。目前“在新标签中打开”打开一个窗口有hidden。另请注意:隐藏的窗口最终也可以由机器人或无头浏览器打开。【参考方案2】:

除了 JavaScript 中的 history.length 之外,您还可以读取/写入窗口的名称。

因此,如果您检查它是否有名称 onload...它应该在第一次加载时为空白...如果您随后将其设置为“foo”...在该窗口中加载... window.name 属性将返回“foo”...除非您在新选项卡/窗口中打开链接...该新窗口不应设置名称。

(当然,除非您通过 window.open(url, name, features); 打开一个弹出窗口,它允许您预先设置名称)

<script>
 if(window.name == '')
   //first load (or Nth load in a new Tab/Window)
   if(!SOME_VALUE_SET_FOR_2ND_TO_NTH_LOADS)
     //set name so we can catch new Tab/Window
     window.name = 'myWinName';
    else 
     //we have a new Tab/Window (or something funky)
     alert('What?! One window not cool enough for ya?\n' +
       'Calling the InterWeb Police!');
   
  else if(window.name == 'myWinName')
   //2nd-Nth load
   document.title = 'All is well... we think';
 
</script>

注意事项:

如果您的页面最初加载在一个已经有名称的窗口/框架中......事情会变得古怪 如果您的页面具有(命名的)iframe,并且您有任何指向这些 iframe 的链接,则 IE7/8 中存在一个错误,即当用户在新选项卡/窗口中打开这些链接时,新选项卡/窗口将“继承“最初定位的 iframe 的名称(非常奇怪的错误,没有预期的修复)

【讨论】:

这是一个巧妙的技巧 :-) 我必须亲自尝试才能看到它的工作原理。如果我理解这一点,您会假设您有一个应用程序的入口页面,其中 window.name 始终假定为空白 - 在进入该页面时您设置了一个已知值。在同一选项卡中的每个其他页面上,window.name 都会被保留。但是,如果您打开选项卡,则 window.name 会丢失。此时,您的脚本会检查 window.name 是否不为空,并且由于您不在第一个条目页面上,因此您检测到打开了一个新选项卡。非常整洁!【参考方案3】:

这是我在 ASP.NET MVC 中用来禁止经过身份验证的用户打开多个选项卡的方法:

<script language="javascript" type="text/javascript">
    @if(Request.IsAuthenticated)
    
        <text>
        if (window.name != 'singleWindow') 
            window.location.href = "Content/ErrorPages/SingleTab.htm";
         
        </text>
    
    else
    
        <text>
        window.name = "singleWindow";
        </text>
    
</script>

基本上,这会在用户第一次访问登录页面时设置窗口名称。登录后,对于每个后续页面加载,都会测试窗口名称。

两个问题:

如果禁用 JavaScript,则无法正常工作 如果用户错误地关闭了原始选项卡,然后在地址栏中粘贴了指向我网站的其他链接,用户将始终收到错误页面。为了给用户一个恢复的机会,我在 SingleTab.htm 页面中包含了“注销”链接,这样用户就可以销毁他的会话 cookie 并开始一个新的会话。

【讨论】:

【参考方案4】:

JavaScript 中的 window.opener 属性将指向打开新窗口的窗口。但是,它不区分新窗口和新选项卡。选项卡不是 W3C 官方规范的一部分,因此没有对它们的直接支持。

【讨论】:

当我“在新标签页中打开链接”时,在 Firefox 中,window.opener 对我来说是空的。 window.opener 仅在使用 js window.open 时设置,而不是通过用户对 A 标签的操作。 window.opener 在锚标记上设置“target”属性时也会设置。【参考方案5】:

简短的回答是,不。长答案是,如果您正在从您的页面对服务器端方法进行 ajaxy 调用,这可能会使窗口保持打开状态(在短时间内调用)。这将是一个草率、不可靠的混乱,而且您无法区分新窗口或标签。

【讨论】:

【参考方案6】:

我真的不这么认为。据我所知,最接近的方法是监视按键和鼠标点击事件,以尝试将操作与在新选项卡中打开链接的常用方法相匹配。 (即,如果他们在单击或中键时按住 Command,则可能是一个新选项卡)。但这并不可靠,因为这些绑定中的任何一个都可以更改。

【讨论】:

【参考方案7】:

这是客户端行为,所以我认为您可以使用 javascript 做一些事情,例如检查浏览器历史记录,但在新标签页和新窗口之间存在歧义。

除此之外,并非所有浏览器都有选项卡,并且并非所有浏览器对选项卡的含义都相同(在某些情况下是不同的过程,在某些情况下则不是)。

但是,你为什么要检查呢?您的应用程序是否在新选项卡中执行真的很重要吗?我不这么认为……

【讨论】:

以上是关于是否可以检测用户是否在新选项卡中打开了链接?的主要内容,如果未能解决你的问题,请参考以下文章

在html中如何链接表单提交以在新选项卡中打开并链接相对URL?

是否可以在 Xcode 中按命令单击符号进入新选项卡?

jQuery:检测鼠标单击并在新选项卡中打开目标

使用角度导航时,在新选项卡中打开链接未在新选项卡中打开

如何在新选项卡中打开文件?

SharePoint Online:在现代页面的同一选项卡中打开链接的Webpart