it-swarm.com.de

Injizieren Sie eine Javascript-Funktion in einen Iframe

Dieser Link ( archivierte Version ) beschreibt, wie Code aus einem Skript in einen iframe eingefügt wird:

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);
}

Das ist in Ordnung, aber was ist, wenn ich ein Funktionsobjekt in einen iframe einfügen möchte und es im iframe-Kontext ausführen lassen? Angenommen, ich habe:

function foo () {
    console.log ("Look at me, executed inside an iframe!", window);
}

und ich möchte den Code von foo in einen iframe einfügen? ( function foo könnte dynamisch geladen werden, ich kann es nicht einfach in Anführungszeichen setzen )

Ich habe naiv versucht:

var scriptFooString = "<script>" + foo.toString() + "</script>"

um den Code in Funktion zu bekommen, aber

  • Ich weiß nicht, wie ich es in den iframe einfügen soll HEAD (vielleicht mit jquery?)
  • Ich weiß nicht, ob es der richtige Weg ist
  • Ich weiß nicht, was passiert, wenn die Funktion viel komplexer ist
  • Ich weiß nicht, was mit doppelten und einfachen Anführungszeichen in scriptFooString passiert

Irgendein Hinweis?

30
janesconference

Zunächst einmal können Sie dies nur erreichen, wenn sich Ihr Frame und die Seite, auf der er angezeigt wird, innerhalb derselben Domain befinden (aufgrund domänenübergreifender Regeln).

zweitens können Sie Dom- und Fensterobjekte des Frames direkt über JS bearbeiten:

frames[0].window.foo = function(){
   console.log ("Look at me, executed inside an iframe!", window);
}

um Ihren Frame von einem DOMElement-Objekt abzurufen, können Sie Folgendes verwenden:

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

myFrame.contentWindow.foo = function(){
       console.log ("Look at me, executed inside an iframe!");
}

Beachten Sie, dass der Gültigkeitsbereich in foo NICHT geändert wird, sodass window weiterhin das übergeordnete Fenster usw. in foo ist.

Wenn Sie Code einfügen möchten, der im Kontext des anderen Frames ausgeführt werden muss, können Sie ein Skript-Tag einfügen oder es auswerten:

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

Obwohl der allgemeine Konsens darin besteht, niemals eval zu verwenden, halte ich es für eine bessere Alternative als die DOM-Injektion, wenn Sie dies WIRKLICH tun müssen.

In Ihrem speziellen Fall könnten Sie also Folgendes tun:

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

Hier ist meine Lösung. Ich benutze jquery, um den Inhalt einzufügen, und benutze dann eval, um die Skript-Tags im Kontext dieses Iframes auszuführen:

    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
frumbert