Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript window.open在chrome扩展中返回未定义的_Javascript_Google Chrome_Google Chrome Extension_Popup - Fatal编程技术网

Javascript window.open在chrome扩展中返回未定义的

Javascript window.open在chrome扩展中返回未定义的,javascript,google-chrome,google-chrome-extension,popup,Javascript,Google Chrome,Google Chrome Extension,Popup,我有基于内容脚本的Chrome扩展。我通过内容脚本中的弹出窗口启动登录过程 我用下面的代码打开一个弹出窗口,然后等待它关闭 但是,我从窗口中得到了一个“未定义的”。open方法。有人知道为什么会这样吗 loginwin在下面的代码中是未定义的,尽管弹出窗口使用指定的login\u url打开良好。下面的代码是从我的内容脚本调用的 var loginWin = window.open(login_url, 'LoginWindow', "width=655,height=490"); consol

我有基于内容脚本的Chrome扩展。我通过内容脚本中的弹出窗口启动登录过程

我用下面的代码打开一个弹出窗口,然后等待它关闭

但是,我从
窗口中得到了一个“未定义的”。open
方法。有人知道为什么会这样吗

loginwin
在下面的代码中是
未定义的
,尽管弹出窗口使用指定的
login\u url打开良好。下面的代码是从我的内容脚本调用的

var loginWin = window.open(login_url, 'LoginWindow', "width=655,height=490");
console.log(loginWin);
// Check every 100 ms if the popup is closed.
var finishedInterval = setInterval(function() {
    console.log('checking if loginWin closed');
    if (loginWin.closed) {
        clearInterval(finishedInterval);
        console.log('popup is now closed');
        Backbone.history.navigate('index', true);
    }
}, 1000);
注:此答案已过时window.open()
总是返回
null
(当弹出窗口被阻止时)或
窗口
对象。以下信息仅适用于非常旧(2012)的Chrome版本


内容脚本无法访问页面的全局
窗口
对象。对于内容脚本,以下内容适用:

  • 窗口
    变量不引用页面的全局对象。相反,它指的是一个新的上下文,即页面上的一个“层”。页面的DOM是完全可访问的
给定一份包含以下内容的文件:  <代码>:

  • 对框架内容的访问受到页面内容的限制;扩展的权限不会放宽策略
  • frames[0]
    frames['frameName']
    ,(通常指框架的包含全局
    窗口的
    对象)是
    未定义的
  • var-iframe=document.getElementById('frameName')
    
    • iframe.contentDocument
      返回包含框架的
      文档
      对象,因为内容脚本可以访问页面的DOM。当应用同一原产地策略时,此属性为空
    • iframe.contentDocument.defaultView
      (指与文档关联的
      窗口
      对象)未定义
    • iframe.contentWindow
      未定义
如您所见,
window.open()
不会返回
window
实例(也不会返回
window.opener
,以此类推)


选择
  • ,以便它在页面的上下文中运行。注意:仅当您操作的页面可以信任时才使用此方法。要在注入脚本和内容脚本之间进行通信,可以使用:

    var login_url = 'http://example.com/';
    var event_name = 'robwuniq' + Math.random().toString(16); // Unique name
    document.addEventListener(event_name, function localName() {
        document.removeEventListener(event_name, localName); // Clean-up
        // Your logic:
        Backbone.history.navigate('index', true);
    });
    // Method 2b: Inject code which runs in the context of the page
    var actualCode = '(' + function(login_url, event_name) {
        var loginWin = window.open(login_url, 'LoginWindow', "width=655,height=490");
        console.log(loginWin);
        // Check every 100 ms if the popup is closed.
        var finishedInterval = setInterval(function() {
            console.log('checking if loginWin closed');
            if (loginWin.closed) {
                clearInterval(finishedInterval);
                console.log('popup is now closed');
                // Notify content script
                var event = document.createEvent('Events');
                event.initEvent(event_name, false, false);
                document.dispatchEvent(event);
            }
        }, 1000);
    } + ')(' + JSON.stringify(login_url+'') + ', "' + event_name + '")';
    var script = document.createElement('script');
    script.textContent = actualCode;
    (document.head||document.documentElement).appendChild(script);
    script.parentNode.removeChild(script);
    
  • 使用
    window.open()
    从后台页面启动窗口。这将返回一个
    窗口
    对象,该对象具有可靠的
    关闭属性。有关通信流的更多详细信息,请参见下一个要点

  • 从内容脚本到。在背景页面中,使用打开一个窗口。在回调中,分配和/或事件。触发这些事件侦听器时,它们应该删除自身,并使用
    chrome.extension.onMessage
    sendResponse
    功能通知原始调用方(内容脚本)
在我的例子中,Chrome阻止了弹出窗口,用户必须通过单击窗口右上角的“阻止的弹出窗口”图标来解除阻止。(他们还可以在Chrome设置中的“内容设置…”下启用/禁用异常。)

我建议在window.open()之后添加一些代码,以便用户知道该做什么。例如:

if (!loginWin)
    alert("You must first unblock popups and try again for this to work!");

您确定在代码中的某个地方声明了login\u url变量吗?是的,正如我所提到的,弹出窗口可以打开指定的url。@Rob…非常感谢您的详细回复。我还没有试过你的解决办法。我会在这个周末尝试,并将你的答案标记为已接受。谢谢Rob,效果很好。这是我遵循的方法,content_脚本向后台脚本发送消息。后台脚本打开一个窗口,然后等待它关闭。然后,服务器将用户重定向到登录成功页面。登录成功页面将关闭窗口。一旦关闭,一条消息将发送回内容脚本。有一件事我不明白,我怎么知道登录过程是否顺利进行?因为用户可以在不登录的情况下关闭登录窗口。我可以为此重新查询服务器,但不知何故它听起来并不整洁。您可以使用
chrome.extension.executeScript
chrome.tabs.onUpdate
(过滤器:
状态=='complete'
)在弹出窗口中插入内容脚本。然后,在文档中查找标识登录状态的唯一节点。很棒的awnser,只是一个简单的问题(如果我阅读了所有这些页面,我可以自己正确地阅读),bullet 3的原因只是背景页面和弹出窗口之间的通信,对吗?。。。如果您只是在页面上构建一个“打印视图”,那么就没有明显的理由不坚持解决方案2,对吗?。。。这是正确的,还是有任何其他缺点?第三个要点解决了问题的要求,即必须监控窗口的状态(是否已关闭?)。如果您只想打开一个窗口,请使用
window.open()或。