简体   繁体   English

将 javascript 函数注入 Iframe

[英]inject a javascript function into an Iframe

This link ( archived version ) describes how to inject code from a script into an iframe: 此链接存档版本)描述了如何将脚本中的代码注入 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);
}

That's ok, but what if I want to insert a function object into an iframe and get it executed in the iframe context ?没关系,但是如果我想将函数对象插入 iframe并让它在 iframe 上下文中执行怎么办? Let's say I have:假设我有:

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

and I want to insert foo's code inside an iframe?我想在 iframe 中插入 foo 的代码? ( function foo could be something loaded dynamically, I can't just wrap it in quotes ) 函数 foo 可能是动态加载的东西,我不能把它用引号括起来

I naively tried:我天真地尝试:

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

to get the code inside function, but获取函数内部的代码,但是

  • I don't know how to insert it in the iframe HEAD (maybe with jquery?)我不知道如何将它插入 iframe HEAD(也许用 jquery?)
  • I don't know if it's the right way不知道这样对不对
  • I don't know what happens when if function is way more complex than that我不知道当 if 函数比那更复杂时会发生什么
  • I don't know what happens with double and single quotes in scriptFooString我不知道scriptFooString双引号和单引号会发生什么

Any hint?任何提示?

First of all you can only accomplish this if your frame and the page displaying it is within the same domain (Due to cross-domain rules)首先,只有当您的框架和显示它的页面在同一个域中时,您才能完成此操作(由于跨域规则)

secondly you can manipulate dom and window objects of the frame directly through JS:其次你可以直接通过JS操作框架的dom和window对象:

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

to get your frame from a DOMElement object you can use:要从 DOMElement 对象中获取您的框架,您可以使用:

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

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

Note that the scope in foo is NOT changed, so window is still the parent window etc. inside foo.请注意,foo 中的范围没有改变,因此 window 仍然是 foo 中的父窗口等。

If you want to inject some code that needs to be run in the context of the other frame you could inject a script tag, or eval it:如果你想注入一些需要在另一个框架的上下文中运行的代码,你可以注入一个脚本标签,或者对其进行评估:

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

Though the general consensus is to never use eval, I think its a better alternative than DOM injection if you REALLY need to accomplish this.虽然普遍的共识是永远不要使用 eval,但我认为如果你真的需要完成这个,我认为它比 DOM 注入更好。

So in your specific case you could do something like:因此,在您的特定情况下,您可以执行以下操作:

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

Here's my solution.这是我的解决方案。 I'm using jquery to insert the content, then using eval to execute the script tags in the context of that iframe:我使用 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);
    });

This code is the result of my research.这段代码是我研究的结果。 The accepted answer also helped me a lot.接受的答案也对我有很大帮助。 First of all, I create a simple iframe:首先,我创建了一个简单的 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>

For access to iframe's window and document I used this code.为了访问 iframe 的窗口和文档,我使用了此代码。

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

Finally I injected js codes into iframe:最后我在 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);

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM