简体   繁体   English

如何检查哪个选项卡打开了(弹出)窗口?

[英]How can I check which tab opened a (popup) window?

The problem问题

I've had this issue for months now, but the concept is pretty straightforward: I want to block some Malicious Site™ from programmatically opening tabs or popup windows.我已经有这个问题几个月了,但这个概念非常简单:我想阻止一些 Malicious Site™ 以编程方式打开选项卡或弹出窗口。

With the chrome.tabs API , I can listen with onCreated when a new tab is created, and I can easily check who (ie which tab) opened that particular tab accessing the openerTabId property of the Tab object passed to the callback function.使用chrome.tabs API ,我可以在创建新选项卡时使用onCreated进行侦听,并且我可以轻松检查谁(即哪个选项卡)打开了该特定选项卡,访问传递给回调函数Tab对象的openerTabId属性

Now, I would like to do the exact same thing when a new window is created : I would like to know which tab opened the window (if any, because it could have been opened by the user too), check its URL to see if it is the Malicious Site™, and act accordingly (ie block the popup).现在,我想在创建新窗口时做完全相同的事情:我想知道哪个选项卡打开了窗口(如果有,因为它也可能被用户打开),检查它的 URL 以查看是否它是 Malicious Site™,并采取相应措施(即阻止弹出窗口)。 I tried doing it in the exact same way: request the array of tabs in the new window and check their openerTabId property, but unfortunately such property is not defined!我尝试以完全相同的方式执行此操作:在新窗口中请求选项卡数组并检查其openerTabId属性,但不幸的是未定义此类属性! I searched the documentation and Googled for hours, but sadly it looks like there's no simple way to check who opened a window.我搜索了文档并用谷歌搜索几个小时,但遗憾的是,似乎没有简单的方法来检查谁打开了一个窗口。

A very clumsy solution一个非常笨拙的解决方案

Stated the above, the only way I was able to do something even remotely close to what I really want, is the following:如上所述,我能够做一些甚至远接近我真正想要的事情的唯一方法是:

  1. Every time a new window is created , its ID is added to an array called windowWatchlist .每次创建窗口时,其 ID 都会添加到名为windowWatchlist的数组中。
  2. Every time a tab is updated (NB: updated, not created), a script is injected inside it to check its document.referrer , which should contain the URL of the site which opened the tab: if the referrer URL contains the address of the Malicious Site™ I want to block popups from, the window is then closed and removed from the windowWatchlist .每次更新选项卡(注意:更新,未创建)时,都会在其中注入一个脚本以检查其document.referrer ,其中包含打开该选项卡的站点的 URL:如果引用 URL 包含恶意站点™ 我想阻止弹出窗口,然后关闭窗口并将其从windowWatchlist删除。
  3. Every time a window is closed , if its ID is in the windowWatchlist , it gets removed from it.每次关闭窗口时,如果它的 ID 在windowWatchlist ,它就会从中删除。

Here's the code (which runs in my background.js script):这是代码(在我的background.js脚本中运行):

// Called on chrome.windows.onCreated
function watchPopupWindow(window) {
    windowWatchlist.push(window.id);
    console.log('Added window #' + window.id + ' to watchlist.');
}

// Called on chrome.windows.onRemoved
function unwatchPopupWindow(windowID) {
    var index = windowWatchlist.indexOf(windowID);

    // If the windowID is in the watchlist:
    if (index != -1) {
        // Remove it:
        windowWatchlist.splice(index, 1);
        console.log('Removed window #' + windowID + ' from watchlist.');
    }
}

// Called on chrome.tabs.onUpdated
function blockPopupWindow(tabID, info, tab) {
    // If this tab is in a window which is in the watchlist:
    if (windowWatchlist.indexOf(tab.windowId) != -1 && info.url && info.url != 'about:blank') {
        // Check the referrer of this tab:
        chrome.tabs.executeScript(tabID, {code: 'document.referrer;'}, function(ref) {
            // If the referrer is the malicious site to block:
            if (ref && ref[0] && ref[0].indexOf("http://MALICIOUS-SITE.XXX") != -1) {
                // Close the popup window:
                chrome.windows.remove(tab.windowId, function() {
                    console.log('Blocked popup window #' + tab.windowId + '.');

                    if (chrome.runtime.lastError)
                        console.error(chrome.runtime.lastError.message);
                });;
            }
        });
    }
}

var windowWatchlist = [];

chrome.windows.onCreated.addListener(watchPopupWindow, {windowTypes: ['popup']});
chrome.windows.onRemoved.addListener(unwatchPopupWindow, {windowTypes: ['popup']});
chrome.tabs.onUpdated.addListener(blockPopupWindow);

Now, you may be wondering: why do you need all this mess only to check a referrer?现在,您可能想知道:为什么只需要检查引用者就需要所有这些混乱? Couldn't you just check the tabs contained in the window when the window is opened and check their referrer directly inside the callback of chrome.window.onCreated ?难道你不能在窗口打开时检查窗口中包含的选项卡,并直接在chrome.window.onCreated的回调中检查它们的引用吗? That's a clever question, and the answer is simple: the problem is that I cannot check the referrer of the tabs right when they are created, because they almost always need some time to load , and the referrer isn't loaded until the page starts loading inside the tab.这是一个聪明的问题,答案很简单:问题是我无法在创建选项卡时立即检查它们的引用,因为它们几乎总是需要一些时间来加载,并且引用直到页面开始才会加载在选项卡内加载。 Therefore, I need to check when a tab is updated , see if its window is in my watchlist, and then check its referrer.因此,我需要检查选项卡何时更新,查看其窗口是否在我的监视列表中,然后检查其引用。 This is why chrome.tabs.onUpdated is needed, since it fires its listeners whenever a tab changes state (eg tab.status changes from "loading" to "complete" ).这就是需要chrome.tabs.onUpdated原因,因为它会在选项卡更改状态时触发其侦听器(例如tab.status"loading"更改为"complete" )。

Why this solution doesn't work为什么此解决方案不起作用

The reason why I call this solution "clumsy" and the reason why it doesn't really work should be already clear to anyone with some experience of JavaScript and web developing: document.referrer isn't reliable at all , and is very often undefined or (in case of multiple redirects) not the right one.我称此解决方案为“笨拙”的原因以及它实际上不起作用的原因对于具有一些 JavaScript 和 Web 开发经验的人来说应该已经很清楚: document.referrer根本不可靠,并且通常是undefined或者(在多次重定向的情况下)不是正确的。 This makes my script fail about 90% of the times, because it is unable to determine whether the popup window was opened by the Malicious Site™ or not.这使我的脚本在大约 90% 的情况下失败,因为它无法确定弹出窗口是否由 Malicious Site™ 打开。

Moreover, the Malicious Site™ often opens popups with URL about:blank or no URL at all, and only when they are loaded, injects data into them, making them basically impossible to detect, even with chrome.tabs.onUpdated which doesn't fire any listener in this situation.此外,Malicious Site™ 经常打开带有 URL about:blank或根本没有 URL 的弹出窗口,并且只有在加载它们时才会向其中注入数据,这使得它们基本上无法被检测到,即使使用chrome.tabs.onUpdated也不行在这种情况下解雇任何侦听器。

I could decide to block any popup with URL about:blank or undefined , and this is what I'm doing right now indeed, but is a pretty bad compromise, since that I end up closing popups opened by any site which uses this method, and not only the Malicious Site™ I want to block.我可以决定阻止任何带有 URL about:blankundefined弹出窗口,这确实是我现在正在做的事情,但这是一个非常糟糕的妥协,因为我最终关闭了任何使用此方法的站点打开的弹出窗口,不仅是我想要阻止的 Malicious Site™。

In conclusion总之

My question is simple, but I don't know about its solution: does anyone know any other more reliable method which could be used to detect which tab opened a new window?我的问题很简单,但我不知道它的解决方案:有没有人知道其他更可靠的方法可以用来检测哪个选项卡打开了一个新窗口? Nothing comes to my mind, maybe something could be possible using the chrome.webRequest API ?我什么都没想,也许可以使用chrome.webRequest API chrome.webRequest什么? I don't really know.我真的不知道。 For months I've been accepting the fact that a simple solution just wasn't possible, and helplessly waited for an update or something, but I never actually thought about asking here, because the problem looked above the competence of an average Chrome Extension programmer, but hopefully I was wrong.几个月以来,我一直接受一个简单的解决方案是不可能的事实,无奈地等待更新或其他什么,但我从来没有真正想过在这里问,因为这个问题超出了普通 Chrome 扩展程序程序员的能力,但希望我错了。


UPDATE : The solution to inject a script inside the site and replace the window.open function with something else isn't viable: if an <iframe> is loaded without a src attribute, but with an already written DOM inside the srcdoc attribute, Chrome will not execute a content script inside it, even if the call to chrome.tabs.executeScript is made with allFrames: true , and even if the content script is declared inside the extension's manifest.更新:在站点内注入脚本并用其他东西替换window.open函数的解决方案是不可行的:如果加载<iframe>没有src属性,但在srcdoc属性中已经写入了 DOM,Chrome不会在其中执行内容脚本,即使对chrome.tabs.executeScript的调用是使用allFrames: true ,并且即使内容脚本在扩展的清单中声明。

I came across the same problem and found the webNavigation.onCreatedNavigationTarget event that yields the source tab/frame id when a new window is opened.我遇到了同样的问题,发现webNavigation.onCreatedNavigationTarget事件会在打开新窗口时产生源选项卡/框架 ID。

Solution found from this post: Is it possible to determine a tab's opener within a Google Chrome extension?从这篇文章中找到的解决方案: Is it possible to determine a tab's opener within a Google Chrome extension?

Since you are already doing code injection this is what I would do.由于您已经在进行代码注入,这就是我要做的。

Inject code to override window.open and have it window.postMessage to child window telling them who opened them.注入代码来覆盖window.open并将window.postMessage传递给子窗口,告诉他们谁打开了它们。 Also will need to inject code to listen to the effect of window.addEventListener('message', messageHandler) which will decided if they should window.close() .还需要注入代码来监听window.addEventListener('message', messageHandler)的效果,这将决定是否应该使用window.close()

On second though I think I would just override window.open and not even open the child windows if you don't want to allow a give site to open windows.其次,如果您不想让给定站点打开窗口,我认为我只会覆盖window.open甚至不打开子窗口。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 新窗口或标签现在打开,我该如何检查 - new window or tab is opened now, How can i check it 如何测试打开的命名窗口或被弹出窗口阻止程序阻止的命名窗口? - How can I test if a named window is opened or was blocked by a popup blocker? 如何使用 JavaScript 从新选项卡中关注打开的弹出窗口 window - How to focus on opened popup window from a new tab using JavaScript 在javascript中打开子弹出窗口后,如何从子窗口访问父窗口? - How can I access a parent window from a child window after a child popup is opened in javascript? 如何使用jQuery / JavaScript打开弹出窗口/标签(ASPX登录页面),然后将值传递给已打开的窗口/标签上的DOM就绪事件? - How do I use jQuery/JavaScript to open a Popup Window/Tab (ASPX Login Page) & then pass values to opened window/tab on DOM Ready Event of it? 如何通过单击弹出窗口中的按钮将打开弹出窗口的窗口重定向到新页面? - How do I redirect the window that opened a popup window to a new page by clicking a button in the popup window? 如何检查浏览器窗口/选项卡是否聚焦? - How can I check whether a browser window/tab is focused? 如何访问新打开的选项卡的窗口对象? [在Firefox扩展程序中] - How can I access a newly-opened tab's window object? [in a firefox extension] porthole.js-如何关闭使用window.open()从新标签页打开的标签页 - porthole.js - how can I close a tab that I opened using window.open(), but from the new tab 如何触发对新打开的窗口/选项卡的单击? - How do I trigger a click on newly opened window /tab?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM