Dom 将javascript函数注入Iframe

Dom 将javascript函数注入Iframe,dom,iframe,head,javascript,Dom,Iframe,Head,Javascript,()描述如何将脚本中的代码注入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'

()描述如何将脚本中的代码注入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=“”+foo.toString()+”

获取函数内部的代码,但是

  • 我不知道如何将它插入iframe头部(可能使用jquery?)
  • 我不知道这是不是正确的方法
  • 我不知道当if函数比那个复杂得多时会发生什么
  • 我不知道
    scriptFooString

有什么提示吗?

首先,如果您的框架和显示它的页面在同一个域中(由于跨域规则),您只能完成此操作

其次,您可以直接通过JS操作框架的dom和窗口对象:

frames[0].window.foo = function(){
   console.log ("Look at me, executed inside an iframe!", window);
}
要从DomeElement对象获取帧,可以使用:

var myFrame = document.getElementById('myFrame');

myFrame.contentWindow.foo = function(){
       console.log ("Look at me, executed inside an iframe!");
}
注意,foo中的作用域没有改变,所以window仍然是foo中的父窗口等

如果要注入一些需要在另一帧的上下文中运行的代码,可以注入脚本标记,或对其求值:

frames[0].window.eval('function foo(){ console.log("Im in a frame",window); }');
尽管普遍的共识是永远不要使用eval,但我认为如果您真的需要实现这一点,它是比DOM注入更好的选择

因此,在您的具体情况下,您可以执行以下操作:

frames[0].window.eval(foo.toString());

这是我的解决办法。我使用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);
    });

这段代码是我研究的结果。被接受的答案对我也有很大帮助。 首先,我创建了一个简单的iframe:


为了访问iframe的窗口和文档,我使用了以下代码

const-iframe=document.getElementById('myiframe');
常量iframeWin=iframe.contentWindow | | iframe;
const iframeDoc=iframe.contentDocument | | iframeWin.document;
最后,我将js代码注入iframe:

var script=iframeDoc.createElement(“脚本”);
script.append(`
window.onload=函数(){
document.getElementById(“fire”).addEventListener('click',function(){
const text=document.getElementById('title').innerText;
警报(文本);
})
}
`);
iframeDoc.documentElement.appendChild(脚本);
演示:

Ok,但是如果我从父窗口执行函数,并使用
frames[0].window.foo(),它将在父窗口上下文中执行。将其插入头部会使其与iframe上下文一起执行,我错了吗?(参见)问题不在于背景,而在于范围。当您创建函数foo时,我相信您是在当前范围内创建的,因此窗口是父窗口而不是框架等。您仍然需要在函数内使用
myFrame.contentWindow
frames[0]。窗口
,以访问正确的范围。如果您需要注入脚本标记,可以通过DOM追加它。我已经更新了我的答案,以便更好地匹配您的查询。虽然我必须说,如果你需要做这样的事情,很可能是你把事情复杂化了,而且你做得不对,或者可能做得更聪明。我需要在沙箱中执行动态加载的插件(带requirejs)。你知道有更好的方法吗?