将JavaScript函数注入iframe

时间:2013-04-24 14:17:13

标签: dom iframe head javascript

This linkarchived version)介绍了如何将代码从脚本注入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
  • 中的双引号和单引号会发生什么

任何提示?

3 个答案:

答案 0 :(得分:31)

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

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

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

如果你想注入一些需要在另一帧的上下文中运行的代码,你可以注入一个脚本标记,或者评估它:

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

虽然普遍的共识是永远不会使用eval,但我认为如果你真的需要实现这个,它是一个比DOM注入更好的选择。

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

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

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

<iframe id="myiframe" width="200" height="200" srcdoc="<h1 id='title'>Hello from Iframe</h1><button type='button' id='fire'>Click Me!</button>
"></iframe>

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

const iframe = document.getElementById('myiframe');
const iframeWin = iframe.contentWindow || iframe;
const iframeDoc = iframe.contentDocument || iframeWin.document;

最后我在 iframe 中注入了 js 代码:

var script = iframeDoc.createElement("script");
  script.append(`
    window.onload = function() {
     document.getElementById("fire").addEventListener('click', function() {
        const text = document.getElementById('title').innerText;
        alert(text);
     })
  }
`);
  iframeDoc.documentElement.appendChild(script);

演示: https://jsfiddle.net/aliam/1z8f7awk/2/