This link(archived version)介绍了如何将代码从脚本注入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);
}
没关系,但如果我想将一个函数对象插入iframe 并在iframe上下文中执行,该怎么办?假设我有:
function foo () {
console.log ("Look at me, executed inside an iframe!", window);
}
我想在iframe中插入foo的代码? (函数foo可以是动态加载的东西,我不能只用引号将其包装)
我天真地试过:
var scriptFooString = "<script>" + foo.toString() + "</script>"
获取函数内部的代码,但
scriptFooString
任何提示?
答案 0 :(得分:31)
首先,如果您的框架和显示它的页面位于同一个域内(由于跨域规则),您只能完成此操作
其次,您可以通过JS直接操作框架的dom和window对象:
frames[0].window.foo = function(){
console.log ("Look at me, executed inside an iframe!", window);
}
从您可以使用的DOMElement对象中获取帧:
var myFrame = document.getElementById('myFrame');
myFrame.contentWindow.foo = function(){
console.log ("Look at me, executed inside an iframe!");
}
请注意,foo中的范围不会更改,因此窗口仍然是foo内的父窗口等。
如果你想注入一些需要在另一帧的上下文中运行的代码,你可以注入一个脚本标记,或者评估它:
frames[0].window.eval('function foo(){ console.log("Im in a frame",window); }');
虽然普遍的共识是永远不会使用eval,但我认为如果你真的需要实现这个,它是一个比DOM注入更好的选择。
因此,在您的具体情况下,您可以执行以下操作:
frames[0].window.eval(foo.toString());
答案 1 :(得分:2)
这是我的解决方案。我正在使用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);
});
答案 2 :(得分:2)
这段代码是我研究的结果。接受的答案也对我有很大帮助。 首先,我创建了一个简单的 iframe:
<iframe id="myiframe" width="200" height="200" srcdoc="<h1 id='title'>Hello from Iframe</h1><button type='button' id='fire'>Click Me!</button>
"></iframe>
为了访问 iframe 的窗口和文档,我使用了此代码。
const iframe = document.getElementById('myiframe');
const iframeWin = iframe.contentWindow || iframe;
const iframeDoc = iframe.contentDocument || iframeWin.document;
最后我在 iframe 中注入了 js 代码:
var script = iframeDoc.createElement("script");
script.append(`
window.onload = function() {
document.getElementById("fire").addEventListener('click', function() {
const text = document.getElementById('title').innerText;
alert(text);
})
}
`);
iframeDoc.documentElement.appendChild(script);