2013-04-24 68 views
22

This linkarchived version)介绍如何从脚本代码注入到一个iframe:注入的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'; // 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>"

进去函数的代码,但

  • 我不知道如何将它插入iframe HEAD(也许用jQuery?)
  • 我不知道它是否是正确的方式
  • 我不知道,如果函数比这样更复杂的时候会发生什么
  • 我不知道有什么用双和单引号scriptFooString

任何暗示会发生什么?

回答

22

你只能如果做到这一点首先你的框架和页面显示是同一域内(由于跨域规则)

其次,你可以直接通过操纵框架的DOM和窗口对象JS:

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内的父窗口等。

如果要注入一些代码,需要在其他框架的背景下运行,你可以注入一个脚本标记,或EVAL它:

frames[0].window.eval('function foo(){ console.log("Im in a frame",window); }'); 

虽然普遍的共识是从来没有使用eval ,如果你真的需要完成这个,我认为它比DOM注入更好。

因此,在特定情况下,你可以这样做:

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

好了,但如果我从父窗口'帧执行功能[0]。 window.foo();',它会在父窗口上下文中执行。将它插入头部会让它在iframe上下文中执行,我错了吗? (请参阅http://jsfiddle.net/7rEXT/) – janesconference 2013-04-24 14:38:09

+0

问题不在于语境,而在于范围。当你制作函数foo时,你可以在我认为的当前范围内进行设置,所以窗口就是父窗口,而不是框架等等。你仍然需要在内部使用'myFrame.contentWindow'或'frames [0] .window'访问正确范围的函数。如果您需要注入脚本标记,则可以通过DOM追加它。 – EJTH 2013-04-25 06:55:00

+0

我已更新我的答案,以更好地匹配您的查询。虽然我必须说,如果你需要做这样的事情,很可能是你过于复杂,而且你做错了,或者做得更聪明。 – EJTH 2013-04-25 07:13:45

1

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