将 javascript 函数注入 Iframe
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16194398/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
inject a javascript function into an Iframe
提问by janesconference
This link(archived version) describes how to inject code from a script into an iframe:
此链接(存档版本)描述了如何将脚本中的代码注入 iframe:
function injectJS() {
var iFrameHead = window.frames["myiframe"].document.getElementsByTagName("head")[0];
var myscript = document.createElement('script');
myscript.type = 'text/javascript';
myscript.src = 'myscript.js'; // replace this with your SCRIPT
iFrameHead.appendChild(myscript);
}
That's ok, but what if I want to insert a function object into an iframe and get it executed in the iframe context? Let's say I have:
没关系,但是如果我想将函数对象插入 iframe并让它在 iframe 上下文中执行怎么办?假设我有:
function foo () {
console.log ("Look at me, executed inside an iframe!", window);
}
and I want to insert foo's code inside an iframe? (function foo could be something loaded dynamically, I can't just wrap it in quotes)
我想在 iframe 中插入 foo 的代码?(函数 foo 可能是动态加载的东西,我不能把它用引号括起来)
I naively tried:
我天真地尝试:
var scriptFooString = "<script>" + foo.toString() + "</script>"
var scriptFooString = "<script>" + foo.toString() + "</script>"
to get the code inside function, but
获取函数内部的代码,但是
- I don't know how to insert it in the iframe HEAD (maybe with jquery?)
- I don't know if it's the right way
- I don't know what happens when if function is way more complex than that
- I don't know what happens with double and single quotes in
scriptFooString
- 我不知道如何将它插入 iframe HEAD(也许用 jquery?)
- 不知道这样对不对
- 我不知道当 if 函数比那更复杂时会发生什么
- 我不知道双引号和单引号会发生什么
scriptFooString
Any hint?
任何提示?
回答by EJTH
First of all you can only accomplish this if your frame and the page displaying it is within the same domain (Due to cross-domain rules)
首先,只有当您的框架和显示它的页面在同一个域中时,您才能完成此操作(由于跨域规则)
secondly you can manipulate dom and window objects of the frame directly through JS:
其次你可以直接通过JS操作框架的dom和window对象:
frames[0].window.foo = function(){
console.log ("Look at me, executed inside an iframe!", window);
}
to get your frame from a DOMElement object you can use:
要从 DOMElement 对象中获取您的框架,您可以使用:
var myFrame = document.getElementById('myFrame');
myFrame.contentWindow.foo = function(){
console.log ("Look at me, executed inside an iframe!");
}
Note that the scope in foo is NOT changed, so window is still the parent window etc. inside foo.
请注意,foo 中的范围没有改变,所以 window 仍然是 foo 中的父窗口等。
If you want to inject some code that needs to be run in the context of the other frame you could inject a script tag, or eval it:
如果你想注入一些需要在另一个框架的上下文中运行的代码,你可以注入一个脚本标签,或者对其进行评估:
frames[0].window.eval('function foo(){ console.log("Im in a frame",window); }');
Though the general consensus is to never use eval, I think its a better alternative than DOM injection if you REALLY need to accomplish this.
虽然普遍的共识是永远不要使用 eval,但我认为如果你真的需要完成这个,我认为它比 DOM 注入更好。
So in your specific case you could do something like:
因此,在您的特定情况下,您可以执行以下操作:
frames[0].window.eval(foo.toString());
回答by frumbert
Here's my solution. I'm using jquery to insert the content, then using eval to execute the script tags in the context of that iframe:
这是我的解决方案。我使用 jquery 插入内容,然后使用 eval 在该 iframe 的上下文中执行脚本标记:
var content = $($.parseHTML(source, document, true));
$("#content").contents().find("html").html(content);
var cw = document.getElementById("content").contentWindow;
[].forEach.call(cw.document.querySelectorAll("script"), function (el, idx) {
cw.eval(el.textContent);
});