admin管理员组文章数量:1336107
I'd like to run some javascript in the context of an iframe's window. Right now the only way I can think to do that is to inject 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 a same-domain iframe, without a src, so I have full access to the contentWindow
.
It's important for my use case that the code runs with the correct globals; window
, document
etc should all be scoped to the iframe itself.
Is there any other way I can do this? The above works, but the script needs to run on different domains all 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've tried myIframe.contentWindow.setTimeout
but that still seems to run the code in the context of the parent window.
I'd like to run some javascript in the context of an iframe's window. Right now the only way I can think to do that is to inject 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 a same-domain iframe, without a src, so I have full access to the contentWindow
.
It's important for my use case that the code runs with the correct globals; window
, document
etc should all be scoped to the iframe itself.
Is there any other way I can do this? The above works, but the script needs to run on different domains all 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've tried myIframe.contentWindow.setTimeout
but that still seems to run the code in the context of the parent window.
4 Answers
Reset to default 3 +200You can actually create that run
function, and then apply a callback function to this
which of course will be the iframe context. Then you can access iframe elements by 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 output
(run) The current window name is: xyz123
You can check my example here: http://zikro.gr/dbg/html/con-frame/
EDIT
If you want to just use window
rather than this.window
, then you can create a parameter to the inline function with he name window
, and then just pass this.window
to that function like this:
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 as expected.
Maybe split the javascript to part run from main window (let's call it main.js
) and from iframe (let's call it iframe.js
). Then in iframe's src
place link to iframe.js
or iframe.html
which loads js file (I'm not sure if you can include javascript straight from src
attribute).
If you load js into the iframe
, use solution at Calling a function inside an iframe from outside the iframe.
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 the .src to frameScript, so the script can load asynchronously. Then you can call postMessage as shown above or call a callback function to notify the parent window.
Note that in your original code window.frameElement.name is initialized. Your script asks then for window.name. FireFox copies the value automatically to the window, causing some confusion.
You need to load the script asynchronously (i.e. $.getScript()
) and then invoke it on .contentWindow
. I haven't 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 helpful if this solution doesn't work: https://plainjs./javascript/ajax/load-a-script-file-asynchronously-49/
Invoking JavaScript code in an iframe from the parent page
本文标签: javascriptRun code in context of frame windowStack Overflow
版权声明:本文标题:javascript - Run code in context of frame window - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742311529a2450967.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论