我有基于内容脚本的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);
答案 0 :(得分:6)
注意:这个答案已经过时了。 Chrome扩展程序中的
window.open()
始终返回null
(当弹出窗口被阻止时)或window
对象。以下信息仅适用于非常旧的(2012)版Chrome。
内容脚本无权访问页面的全局window
对象。对于内容脚本,以下内容适用:
window
变量不引用页面的全局对象。相反,它指的是新的上下文,页面上的“层”。页面的DOM完全可访问。 #execution-environment 鉴于由<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
也不会,等等)。
Inject the code in the page,以便它在页面的上下文中运行。注意:如果您正在操作的页面可以信任,则仅使用此方法。要在注入的脚本和内容脚本之间进行通信,您可以使用:
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()
从后台页面启动窗口。这将返回一个window
对象,该对象具有可靠的closed
属性。有关通信流程的更多详细信息,请参阅下一个要点。
chrome.windows.create
打开一个窗口。在回调中,指定chrome.tabs.onRemoved
和/或chrome.tabs.onUpdated
事件。当触发这些事件侦听器时,它们应自行删除,并使用sendResponse
chrome.extension.onMessage
函数通知原始调用者(内容脚本)。 答案 1 :(得分:2)
在我的情况下,Chrome阻止弹出窗口,用户必须通过单击窗口右上角的“阻止弹出窗口”图标来取消阻止。 (他们还可以在Chrome设置中的“内容设置...”下启用/停用例外。)
我建议在window.open()之后添加一些代码,以便用户知道该怎么做。例如:
if (!loginWin)
alert("You must first unblock popups and try again for this to work!");