Подтвердить что ты не робот

Вставить функцию javascript в iframe

Эта ссылка (заархивированная версия) описывает как ввести код из script в 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);
}

и я хочу вставить foo-код внутри iframe? (функция foo может быть динамически загружена, я не могу просто ее обернуть в кавычки)

Я наивно пробовал:

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

чтобы получить код внутри функции, но

  • Я не знаю, как вставить его в iframe HEAD (возможно, с jquery?)
  • Я не знаю, правильно ли это.
  • Я не знаю, что произойдет, если функция намного сложнее, чем
  • Я не знаю, что происходит с двойными и одинарными кавычками в scriptFooString

Любые подсказки?

4b9b3361

Ответ 1

Прежде всего, вы можете выполнить это только в том случае, если ваш фрейм и страница, отображающая его, находятся в одном домене (из-за правил междоменного доступа)

во-вторых, вы можете манипулировать объектами dom и window фрейма непосредственно через 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.

Если вы хотите ввести некоторый код, который должен быть запущен в контексте другого фрейма, вы можете вставить тег script или eval it:

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

Хотя общий консенсус заключается в том, чтобы никогда не использовать eval, я считаю его лучшей альтернативой, чем инъекция DOM, если вам действительно нужно выполнить это.

Итак, в вашем конкретном случае вы можете сделать что-то вроде:

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

Ответ 2

Вот мое решение. Я использую jquery для вставки содержимого, а затем используя eval для выполнения тегов script в контексте этого 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);
    });