Run code in frame window context

I want to run javascript in the context of an iframe window. Right now, the only way I can do this is to enter a script tag:

myIframe = document.createElement('iframe'); myIframe.setAttribute('name', 'xyz123'); document.body.appendChild(myIframe); myIframe.contentWindow.document.write(` <script> console.log('The current window name is:', window.name); </script> `); 

Note: this is an iframe with the same domain without src, so I have full access to contentWindow .

For my use case, it is important that the code works with the correct global ones; window , document , etc. all should be tied to the iframe itself.

Is there any other way to do this? The above works, but the script should work in different domains with different CSP rules, which means adding support for nonces / hashes, etc.

Is it possible to do something like:

 myIframe.contentWindow.run(function() { console.log('The current window name is:' window.name); }); 

I tried myIframe.contentWindow.setTimeout , but it still seems to run code in the context of the parent window.

+5
source share
4 answers

Maybe break javascript into the part launched from the main window (let it be main.js ) and from iframe (call iframe.js on it). Then in the iframe src put a link to iframe.js or iframe.html that loads the js file (I'm not sure if you can enable javascript directly from the src attribute).

If you load js in an iframe , use the solution in the function call inside the iframe from outside the iframe .

+2
source

In fact, you can create this run function and then apply the callback function to this , which of course will be the iframe context. Then you can access the iframe elements using this :

 myIframe.contentWindow.run = function(fn) { fn.apply(this); }; myIframe.contentWindow.run(function() { console.log('(run) The current window name is:', this.window.name); }); 

Console exit

 (run) The current window name is: xyz123 

Here you can check my example: http://zikro.gr/dbg/html/con-frame/

EDIT

If you want to just use window , not this.window , you can create a parameter for an inline function called window , and then just pass this.window to this function as follows:

 myIframe.contentWindow.run = function(fn) { fn.call(this, this.window); }; myIframe.contentWindow.run(function(window) { console.log('(run) The current window name is:', window.name); }); 

And it still works.

+2
source
 window.name='main window'; // just for debugging var myIframe = document.createElement('iframe'), frameScript = document.createElement('script'); document.body.appendChild(myIframe); frameScript.textContent = "window.top.name='topWindow';window.name = 'xyz123';function WhereAmI(){return(window.name);} window.parent.postMessage('frame_initialized', '*'); " myIframe.contentWindow.document.documentElement.appendChild(frameScript); function OnMessage(event) { if(typeof event.data == 'string') switch(event.data) { case 'frame_initialized': myIframe.contentWindow.document.body.appendChild( document.createTextNode(myIframe.contentWindow.WhereAmI()) ); console.log('Now running in', myIframe.contentWindow.WhereAmI()); break; } } window.addEventListener('message', OnMessage, false); 

Tested with Firefox and Chromium.

Instead of .textContent, you can apply .src to frameScript, so the script can load asynchronously. You can then call postMessage as shown above, or call the callback function to notify the parent window.

Note that window.frameElement.name is initialized in the source code. Your script requests for window.name. FireFox automatically copies the value to the window, causing some confusion.

+1
source

You need to load the script asynchronously (i.e. $.getScript() ) and then call it on .contentWindow . I have not tested, but this should work.

 (function() { var myIframe = document.createElement('iframe#iframe'): var jsSnippet; var iframeScript = function(url) { script = document.createElement('script'), scripts = document.getElementsByTagName('script')[0]; script.src = url; return jsSnippet = scripts.parentNode.insertBefore(script, scripts); }; myIframe.setAttribute('name', 'xyz123'): myIframe.appendChild(jsSnippet); document.body.appendChild(myIframe); return document.getElementById('#iframe').contentWindow.iframeScript(); }) 

These two resources will be useful if this solution does not work: https://plainjs.com/javascript/ajax/load-a-script-file-asynchronously-49/

Call JavaScript code in iframe from parent page

+1
source

Source: https://habr.com/ru/post/1271413/


All Articles