有什么方法可以在 JavaScript 中识别浏览器选项卡?

IT技术 javascript browser tabs uniqueidentifier
2021-02-12 19:12:22

我需要能够在浏览器中识别我所在的选项卡。难道我不能从浏览器中获取一些信息来识别选项卡吗?我不需要知道任何其他选项卡的任何信息,我只需要我所在选项卡的 id。它可以是随机数或序列号,或者日期时间戳,只要它保持不变标签的寿命。

我有一个客户端应用程序,它通过 HTTP 连接到远程服务器,如果我在多个选项卡中打开它,每个实例都需要自己的唯一 ID 或应用程序失败,所以我只需要一些与相关联的唯一编号只要该选项卡存在(即在我浏览提供此应用程序的站点时页面刷新后仍然存在的内容)。看起来很简单,应该只在浏览器中可用,比如 window.tabId - 这就是我所需要的。我有一个严重的开发障碍,因为我无法通过这个似乎不存在的简单、简单、简单的解决方案。必须有一种方法(一种跨浏览器的解决方案)。

有任何想法吗?

6个回答

SessionStorage 是每个选项卡/窗口的,因此您可以在 sessionStorage 中定义一个随机数,如果存在则首先获取它:

var tabID = sessionStorage.tabID ? 
            sessionStorage.tabID : 
            sessionStorage.tabID = Math.random();

更新
在某些情况下,您可能在多个选项卡中有相同的 sessionStorage(例如,当您复制选项卡时)。在这种情况下,以下代码可能会有所帮助:

var tabID = sessionStorage.tabID && 
            sessionStorage.closedLastTab !== '2' ? 
            sessionStorage.tabID : 
            sessionStorage.tabID = Math.random();
sessionStorage.closedLastTab = '2';
$(window).on('unload beforeunload', function() {
      sessionStorage.closedLastTab = '1';
});
随机选择数字并不能确保它们是唯一的(即在 0 到 99 之间随机选择一个数字,并且总是可以多次选择 11)。为什么不是 localStorage 中的序列号?
2021-03-17 19:12:22
对于那些担心重复 ID 的人 - 只需为随机生成 ID 使用基于时间的前缀。
2021-03-17 19:12:22
此代码有很大帮助,但是当您复制窗口时数据存储仍然存在
2021-03-20 19:12:22
会话存储不会在 IE 中持久化。
2021-03-21 19:12:22
@MaxWaterman,是的,随机数可以冲突,但Math.random返回双精度数,大小为 64 位。所以它并没有那么糟糕。Math.random超过一百万次运行生成两个重复数字的概率约为 1%。请参阅此答案stackoverflow.com/a/28220928/3167374Math.random在新版本的浏览器中,质量似乎更好。现在 f.ex。它是 Chrome 内部使用的 128 位生成器(v8.dev/blog/math-random)。(不确定它对碰撞概率的影响有多大。)
2021-04-12 19:12:22

您必须使用 html5,但sessionStorage与随机 guid 相结合似乎是您想要的。

数字可以出现两次,即使它们是随机选择的,不是吗?因此,两个选项卡可能具有相同的编号。我原以为 localStorage 中的序列号会更好 - 当您在新选项卡中打开页面时,增加编号并将其存储在 sessionStorage 中。
2021-04-10 19:12:22
@MaxWaterman:不同的浏览器、私人标签、更改时间……序列比随机更能保证。有多种方法可以创建尽可能好的 guid - 碰撞的可能性很小,以至于不值得打扰。
2021-04-10 19:12:22

由于我没有找到简单的 Javascript 函数作为windows.currentTabIndex,我编写了一些 Javascript 行来在加载时在每个浏览器选项卡上修复 ID。

function defineTabID()
    {
    var iPageTabID = sessionStorage.getItem("tabID");
      // if it is the first time that this page is loaded
    if (iPageTabID == null)
        {
        var iLocalTabID = localStorage.getItem("tabID");
          // if tabID is not yet defined in localStorage it is initialized to 1
          // else tabId counter is increment by 1
        var iPageTabID = (iLocalTabID == null) ? 1 : Number(iLocalTabID) + 1;
          // new computed value are saved in localStorage and in sessionStorage
        localStorage.setItem("tabID",iPageTabID);
        sessionStorage.setItem("tabID",iPageTabID);
        }
    }

此代码保存最后一个选项卡的索引localStorage以更新新选项卡的当前值并sessionStorage修复页面的 id !

我必须defineTabId()在应用程序的每个页面中调用函数。由于我使用 JSF 模板进行开发,因此仅在一个地方定义了 :-)

如果由于某种原因,可以打开多个选项卡,我的函数必须以不同的方式调用。例如,必须在创建其他选项卡的选项卡中之前调用此函数,以便在同一线程中顺序创建多个 tabid !
2021-03-17 19:12:22
如果 2 个不同的代码同时执行此代码,则程序错误。但是在我的情况下,不可能在 2 个并行代码中生成多个选项卡,因为创建新选项卡与人工操作相关联,并且一次只能打开一个选项卡。
2021-03-24 19:12:22
但是,如果此代码在两个并行的同时打开选项卡中运行会怎样?在我看来,有可能是附近的竞争条件getItem-setItem电话。
2021-03-25 19:12:22

这是一种tabId在页面加载后可用的方法-tabId即使在刷新后也保持相同

这也解决了重复的标签的问题,因为tabId从清除sessionStorage

window.addEventListener("beforeunload", function (e)
{
    window.sessionStorage.tabId = window.tabId;

    return null;
});

window.addEventListener("load", function (e)
{
    if (window.sessionStorage.tabId)
    {
        window.tabId = window.sessionStorage.tabId;
        window.sessionStorage.removeItem("tabId");
    }
    else
    {
        window.tabId = Math.floor(Math.random() * 1000000);
    }

    return null;
});

访问tabId使用window.tabId.

beforeunload需要事件以保持tabId刷新后具有相同的可用 id。

load事件需要:

  1. 生成初始tabId.
  2. tabId刷新后加载相同的内容- 如果存在。

* 我真的不知道为什么我应该做return null或返回。只是读到不返回可能会导致函数无法工作:(

您无法使用 javascript 获取标签 ID,但是有什么解决方案可以帮助您在用户打开新标签时使用不同的会话/cookie。

一些参考:

获取浏览器标签索引/ID

从 Firefox 扩展中获取 Firefox 标签的 URL

如何在浏览器选项卡中区分会话?

在每个浏览器选项卡中获取唯一会话

asp.net - 会话 - 多个浏览器选项卡 - 不同的会话?