2013-04-24 97 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); 
    });