window.open在chrome扩展中返回undefined [英] window.open returns undefined in chrome extension
问题描述
我有基于内容脚本的Chrome扩展程序。我通过内容脚本中的弹出窗口启动登录过程。
我用下面的代码打开一个弹出窗口,然后等到它关闭。
然而,我得到来自 window.open
方法的'undefined'。有人知道为什么会发生这种情况吗?
loginwin
是 undefined
在下面的代码中,尽管弹出窗口在指定的 login_url
中可以正常打开。下面的代码是从我的内容脚本中调用的。
var loginWin = window.open(login_url,'LoginWindow',width = 655,高度= 490\" );
console.log(loginWin);
//如果弹出窗口关闭,则每隔100 ms检查一次。
var finishedInterval = setInterval(function(){
console.log('checking the loginWin closed');
if(loginWin.closed){
clearInterval(finishedInterval);
console.log('popup is closed');
Backbone.history.navigate('index',true);
}
},1000);
已过时。 Chrome扩展程序中的
window.open()
总是会返回null
(当弹出窗口被阻止时)或window
对象。以下信息仅适用于非常旧的(2012年)Chrome版本。
内容脚本无法访问页面的全局窗口
对象。对于内容脚本,以下内容适用:
-
窗口
变量不会引用页面的全局对象。相反,它引用了一个新的上下文,即页面上的图层。该页面的DOM是完全可访问的。 #execution-environment
给定一个包含 < iframe id =frameNamesrc =http:// domain />< / iframe>
:
frames [0]
和 frames ['frameName ']
,(通常指的是框架包含的全局窗口
对象)是 undefined $ c
var iframe = document.getElementById('frameName');
iframe.contentDocument
返回 文档$包含框架的c $ c>
对象,因为内容脚本可以访问页面的DOM。此属性为 null
,适用于相同原产地政策。 iframe.contentDocument.defaultView
(引用与文档关联的窗口
对象) undefined 。
iframe.contentWindow
为未定义。$你可以看到, window.open()$ c
Window
实例( window.opener
等等)。
替代品
-
< a href =https://stackoverflow.com/questions/9515704/building-a-chrome-extension-inject-code-in-a-page-using-a-content-script/9517879#9517879>注入代码在页面中,以便它在页面的上下文中运行。注意:如果您正在操作的页面可以信任,请仅使用此方法。要在注入的脚本和内容脚本之间进行通信,您可以使用:
var login_url ='http://example.com /';
var event_name ='robwuniq'+ Math.random()。toString(16); //唯一名称
document.addEventListener(event_name,function localName(){
document.removeEventListener(event_name,localName); //清理
//您的逻辑:
Backbone.history.navigate('index',true);
});
//方法2b:注入在页面上下文中运行的代码
var actualCode ='('+ function(login_url,event_name){
var loginWin = window.open(login_url, 'LoginWindow',width = 655,height = 490);
console.log(loginWin);
//如果弹出窗口关闭,则每隔100毫秒检查
var finishedInterval = setInterval (函数(){
console.log('检查loginWin是否关闭');
if(loginWin.closed){
clearInterval(finishedInterval);
console.log('弹出窗口已关闭');
//通知内容脚本
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.windows。创建
打开一个窗口。在回调中,分配chrome.tabs。 onRemoved
和/或chrome.tabs.onUpdated
事件。当这些事件监听器被触发时,他们应该删除自己,并使用函数
。chrome.extension.onMessage中的 sendResponse
函数通知原始调用者(内容脚本)
I have content script based Chrome extension. I initiate the sign in process through a popup window in the content script.
I open a popup window using the below code and then wait till its closed.
However, I get an 'undefined' from window.open
method. Does anybody know why this happens?
loginwin
is undefined
in below code although the popup window opens up fine with the specified login_url
. The code below is called from my content script.
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);
Note: This answer is obsolete.
window.open()
in a Chrome extension always returns eithernull
(when the popup is blocked) or awindow
object. The information below only applies to very old (2012) versions of Chrome.
Content scripts do not have any access to a page's global window
object. For content scripts, the following applies:
- The
window
variable does not refer to the page's global object. Instead, it refers to a new context, a "layer" over the page. The page's DOM is fully accessible. #execution-environment
Given a document consisting of <iframe id="frameName" src="http://domain/"></iframe>
:
- Access to the contents of a frame is restricted by the Same origin policy of the page; the permissions of your extension does not relax the policy.
frames[0]
andframes['frameName']
, (normally referring to the the frame's containing globalwindow
object) isundefined
.var iframe = document.getElementById('frameName');
iframe.contentDocument
returns adocument
object of the containing frame, because content scripts have access to the DOM of a page. This property isnull
when the Same origin policy applies.iframe.contentDocument.defaultView
(refers to thewindow
object associated with the document) is undefined.iframe.contentWindow
is undefined.
As you can see, window.open()
does not return a Window
instance (neither does window.opener
, and so forth).
Alternatives
Inject the code in the page, so that it runs in the context of the page. Note: Only use this method if the page you're operating on can be trusted. To communicate between the injected script and the content script, you could use:
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);
Launch the window from the background page using
window.open()
. This returns awindow
object which has a reliableclosed
property. See the next bullet point for more details on the communication flow.- From the content script, pass a message to the background page. In the background page, use
chrome.windows.create
to open a window. In the callback, assign anchrome.tabs.onRemoved
and/orchrome.tabs.onUpdated
event. When these event listeners are triggered, they should remove themselves, and notify the original caller (content script) using thesendResponse
function ofchrome.extension.onMessage
.
这篇关于window.open在chrome扩展中返回undefined的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!