window.open在chrome扩展中返回undefined
window.open returns undefined in chrome extension
我有基于内容脚本的Chrome扩展。我通过内容脚本中的弹出窗口启动登录过程。
我用下面的代码打开一个弹出窗口,然后等待它关闭。
但是,我从window.open
方法中得到了一个"未定义"。有人知道为什么会发生这种事吗?
在下面的代码中,loginwin
是undefined
,尽管弹出窗口会以指定的login_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);
注意:这个答案已经过时了。Chrome扩展中的
window.open()
总是返回null
(当弹出窗口被阻止时)或window
对象。以下信息仅适用于非常旧的Chrome(2012)版本。
内容脚本无法访问页面的全局window
对象。对于内容脚本,以下内容适用:
-
window
变量不引用页面的全局对象。相反,它指的是一个新的上下文,即页面上的"层"。页面的DOM是完全可访问的#执行环境
给定一个由 <iframe id="frameName" src="http://domain/"></iframe>
:
- 对框架内容的访问受到页面同源策略的限制;扩展的权限不会放松策略
frames[0]
和frames['frameName']
(通常指包含全局window
对象的帧)是undefined
var iframe = document.getElementById('frameName');
iframe.contentDocument
返回包含帧的document
对象,因为内容脚本可以访问页面的DOM。应用同源策略时,此属性为null
iframe.contentDocument.defaultView
(指与文档关联的window
对象)是未定义的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()
从后台页面启动窗口。这将返回一个具有可靠closed
属性的window
对象。有关通信流程的更多详细信息,请参阅下一个要点。 - 从内容脚本中,向后台页面传递一条消息。在后台页面中,使用
chrome.windows.create
打开一个窗口。在回调中,分配一个chrome.tabs.onRemoved
和/或chrome.tabs.onUpdated
事件。当触发这些事件侦听器时,它们应该删除自己,并使用chrome.extension.onMessage
的sendResponse
函数通知原始调用方(内容脚本)
在我的案例中,Chrome阻止了弹出窗口,用户必须通过单击窗口右上角的"阻止的弹出窗口"图标来取消阻止。(他们还可以在Chrome设置中的"内容设置…"下启用/禁用异常。)
我建议在window.open()之后添加一些代码,以便用户知道该做什么。例如:
if (!loginWin)
alert("You must first unblock popups and try again for this to work!");
- RequireJS向模块传递配置总是返回undefined
- JSON数组数据返回Undefined
- JavaScript”;.方法“;返回undefined
- jQuery可以't获取data-*属性值,返回undefined
- Javascript/JSON警报返回Undefined
- Javascript:firstChild对象返回undefined
- 当尝试使用ajax读取文件时,变量返回undefined
- 如何避免JSON.stringify在特殊情况下返回undefined,从而为JSON.parse创建字符串失败
- 使用谷歌地图:一个返回undefined的自定义javascript函数
- Json在nodeJs和AngularJs中返回undefined
- 为什么像 Firefox 和 Chrome 控制台中的 '}{' 这样的结构会返回 'undefined'?
- 使用 HTML 和 JavaScript 从表单访问值时返回 undefined
- 在 CoffeeScript 中,当尝试调用类中的方法 (@_methodName) 时,它会返回 undefined
- 解析承诺'当'返回undefined(Javascript)
- NodeJS:zlib.gunzip(body)错误地返回“undefined”
- window.open在chrome扩展中返回undefined
- jQuery.pr()返回undefined,而.attr()对数据-*的作用与预期一样
- 正在读取嵌套json,jquery返回undefined
- IIFE是否总是返回undefined
- $timeout包装$http.post返回undefined而不是promise