【问题标题】:Is it possible to determine a tab's opener within a Google Chrome extension?是否可以在 Google Chrome 扩展程序中确定标签的打开器?
【发布时间】:2014-03-27 00:01:50
【问题描述】:

我正在寻找一种方法来确定 Google Chrome 扩展程序中给定标签的打开器(父标签)。

我查看了 Tab 的文档,但似乎没有任何东西可以提供此信息。 http://code.google.com/chrome/extensions/tabs.html

我尝试将此内容脚本注入页面(认为我可以将值传递给我的背景页面):

alert(window.opener);

.. 但它只会产生 null。

到目前为止,我想出的最好的方法是跟踪当前焦点选项卡,并且每当创建新选项卡时,只需假设焦点选项卡是新选项卡的打开器/父选项卡。我相信这会事实上在大多数情况下正确识别父标签,因为后台标签很少(被允许)打开新页面。但是,它有时看起来很笨拙并且可能不准确 - 例如,如果另一个扩展程序打开了新标签页,则此方法可能会错误地识别新标签页的打开器。

【问题讨论】:

  • 请问您/正在构建什么样的扩展?我正在寻找一个非常简单的具有此确切功能的非常简单的功能:每当我怀疑“我来自哪里”或打开了什么内容时,我想知道当前选项卡的父级。您的分机能否为我回答这个问题?或者即使没有,也许你知道类似的扩展?

标签: google-chrome google-chrome-extension


【解决方案1】:

更新:现在可以使用新添加的 webNavigation API,特别是通过挂钩 onCreatedNavigationTarget 事件,在 Chrome 扩展程序中可靠地确定标签的打开器标签。

https://code.google.com/chrome/extensions/trunk/webNavigation.html

【讨论】:

    【解决方案2】:

    Chrome 添加了一个实验性的扩展 API 可以实现这一点——特别是 webNavigation.onBeforeRetarget。 http://code.google.com/chrome/extensions/experimental.webNavigation.html

    但是,由于这仍然是实验性的(不能在 Chrome 稳定版本中使用或在 Chrome 网上应用店中发布),我最终使用了另一种方法。

    基本上:

    在 content_script.js 中:

    chrome.extension.sendRequest({
        request: {
            op: "pageLoadStarted", 
            url: document.location.href, 
            referrer: document.referrer
        }
    }); 
    

    在 background.html 中:

    chrome.extension.onRequest.addListener(function(request, sender, sendResponse) { 
        console.log('onRequest: ' + JSON.stringify(request)); 
        console.log(JSON.stringify(sender)); 
      }); 
    

    这种方法允许我获取标签的referrer,然后我可以将其与现有标签的 url 关联。这并不总是一对一的映射,所以我做了一些额外的魔法,比如如果当前选择的标签页的 URL 与新标签页的引用者匹配,则优先选择它作为开启者。

    这实际上只是一个近似于 webNavigation.onBeforeRetarget 或 window.opener 提供的更简单、更准确的功能的 hack。

    【讨论】:

      【解决方案3】:

      进一步的调查显示,当您认为 onCreatedNavigationTarget() 会指示开启者打开的关系时,它不会总是触发。

      有时可以在 .openerTabId 参数中的 chrome.tabs.onCreated/onUpdated 返回的 Tab 对象中找到附加提示。

      一个全面的解决方案可能不得不依赖这些答案中描述的多种方法。

      【讨论】:

        【解决方案4】:
        port.onMessage.addListener(
             function(msg) {
                 var tabid = port.sender.tab.openerTabId;
                 console.log("Received message from tab that was opened by tab id : " + tabid);
                 // reliably shows the tab id of the tab that opened
                 // the tab sending the message
             }); 
        

        【讨论】: