Overview of the problem
I cannot access the DOM of a window that I open programmatically in my chrome extension. I believe this may be due to origin/cross-site scripting restrictions. I have tried to give it the maximal permissions I can, including "<all_urls>", "activeTab" and "tabs"
I also played around with "content_security_policy_" settings but from the documentation I was hoping rather than expecting that to help.
I have a simple extension that runs code when the button is clicked, I want to open a few different tabs (but from different domains) and then access the DOM of each. However, it only seems to work if I'm on a tab of a domain and then I open another tab of the same of domain. Then I can access, for example, window onload of the new tab. I have no luck when it is a different domain.
e.g. if I press the button with activeTab "foo.com" then if it window.open
s a new tab "foo.com/something" then I can access the document of that opened tab. But if it was "bar.com" then I wouldn't be able to access "foo.com/something"'s DOM
p.s. please note that executeScripts
is used instead of manifest content scripts because it is necessary for my code to work. I must inject at least some of the files there this way, otherwise my code will not work (for reasons that are not completely apparent in the example)
my Question
What's way(s) can I get around this - I mean be able to access the DOM of any tab that I open, regardless of what site is in the active tab when the extension button is pressed in the toolbar?
Should I inject content scripts into a a tab that has been opened with window.open
and somehow pass its document to Code.js
? If so, how could I go about doing that? Can I somehow pass the document to the background.js
? and somehow pass it to the injected Code.js
?
If this will work (get around security restrictions) then can these content scripts be injected programatically (I don't know exactly what sites they will be until runtime, so I can't really specify them in the manifest)
or is there some way I can just relax the security restrictions and be able to directly access window.open
's returned window
's document
? (which as I mentioned above currently only works on same-domain sites)
background.js
// this is the background code...
// listen for our browerAction to be clicked
chrome.browserAction.onClicked.addListener(function (tab) {
executeScripts(null, [ // jquery can be inserted here: https://stackoverflow.com/questions/21317476/how-to-use-jquery-in-chrome-extension
{ file: "lib/jquery-3.2.1.js" },
{ file: "lib/kotlin.js" },
{ file: "Code.js" } // don't include it in manifest "content_scripts" because it gives an error about kotlin.js not present that way
])
});
/*
* https://stackoverflow.com/questions/21535233/injecting-multiple-scripts-through-executescript-in-google-chrome
*/
function executeScripts(tabId, injectDetailsArray)
{
function createCallback(tabId, injectDetails, innerCallback) {
return function () {
chrome.tabs.executeScript(tabId, injectDetails, innerCallback);
};
}
var callback = null;
for (var i = injectDetailsArray.length - 1; i >= 0; --i)
callback = createCallback(tabId, injectDetailsArray[i], callback);
if (callback !== null)
callback(); // execute outermost function
}
code flow
background.js
Code.js
calls a function that starts withvar w = window.open(url)
- then
w.addEventListener("load", ...)
, which is the problem. It only fires if the url belongs to the same domain as the active tab. (onLoad
can't be used any-which-way, it never fires that's why I useaddEventListener
)
notes
- I have
"manifest_version": 2
- I need to inject this way rather than include content scripts in the manifest (I guess I could put the jquery library in the manifest but the others I can't and I prefer to keep all injections together in the "code")