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 awindowobject. 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
windowvariable 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 globalwindowobject) isundefined.var iframe = document.getElementById('frameName');iframe.contentDocumentreturns adocumentobject of the containing frame, because content scripts have access to the DOM of a page. This property isnullwhen the Same origin policy applies.iframe.contentDocument.defaultView(refers to thewindowobject associated with the document) is undefined.iframe.contentWindowis 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 awindowobject which has a reliableclosedproperty. 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.createto open a window. In the callback, assign anchrome.tabs.onRemovedand/orchrome.tabs.onUpdatedevent. When these event listeners are triggered, they should remove themselves, and notify the original caller (content script) using thesendResponsefunction ofchrome.extension.onMessage.
In my case, Chrome was blocking the popup and the user had to unblock by clicking the "blocked popup" icon in the upper-right corner of the window. (They can also enable/disable exceptions under "Content settings..." in Chrome settings.)
I would suggest adding some code after window.open() so that the user knows what to do. For example:
if (!loginWin)
alert("You must first unblock popups and try again for this to work!");
来源:https://stackoverflow.com/questions/11812786/window-open-returns-undefined-in-chrome-extension