从窗口将值传递给 iframe

Posted

技术标签:

【中文标题】从窗口将值传递给 iframe【英文标题】:Pass value to iframe from a window 【发布时间】:2010-10-06 21:32:32 【问题描述】:

我需要向 iframe 发送一个值。

iframe 存在于当前窗口中。我怎样才能做到这一点?

我需要在包含 iframe 的父窗口中使用 javascript

【问题讨论】:

***.com/questions/168455/how-do-you-post-to-an-iframe alfilatov.com/posts/… 【参考方案1】:

在你的主页中,添加这一行-

window.postMessage("Hello data from Homepage");

在你的 iframe 中,添加这一行-

window.addEventListener("message", receiveDataFromWeb);

const receiveDataFromWeb=  (data)=> 
    console.log(data);
    //this should print Hello data from Homepage

【讨论】:

【参考方案2】:

只是另一种方式。 在 iframe 中,您可以添加事件侦听器并将事件分派到父文档中:

parent.document.addEventListener('iframe-event', (e) => 
    console.log('iframe-event', e.detail);
);

setTimeout(() => 
    console.log('dispatchEvent from iframe');
    const event = new CustomEvent('frame-ready',  detail: 'parent event dispatched from iframe' );
    parent.document.dispatchEvent(event);
, 1000);

您可以从父级添加事件侦听器并在其自己的文档中调度事件:

document.addEventListener('frame-ready', (e) => 
        const event = new CustomEvent('iframe-event',  detail: 'iframe event dispatched from parent' );
        document.dispatchEvent(event);
    );

此外,如果在任何情况下您需要在新选项卡中打开此框架,您仍然可以使用事件进行通信。 从你的框架/标签:

if (opener) 
        const event = new CustomEvent('frame-ready',  detail: 'parent event dispatched from new tab' );
        opener.document.dispatchEvent(event);
    

来自您的家长/开场白:

window.open('my-frame.html', '_blank');

document.addEventListener('frame-ready', (e) => 
    const event = new CustomEvent('iframe-event',  detail: 'iframe event dispatched from parent' );
    document.dispatchEvent(event);
);

请注意 window.open 会将您的 DOM 暴露给它打开的下一页,因此如果您使用它打开任何第三方 url,则必须始终使用 rel=noopener 以避免安全问题:

window.open('third-part-url.html', '_blank', 'noopener');

【讨论】:

【参考方案3】:

如果您在内部使用 angular 和 iframe,则需要收听 iframe 以完成加载。你可以这样做:

         document.getElementsByTagName("iframe")[0].addEventListener('load', () => 
            document.getElementsByTagName("iframe")[0].contentWindow.postMessage(
                
                    call: 'sendValue',
                    value: 'data'
                ,
                window.location.origin)
        )

您将不得不以一种或另一种方式获取 iframe(有更好的方法可以在 Angular 中进行),然后等待它加载。否则,即使您在 ngAfterViewInit() 等生命周期方法中执行此操作,侦听器也不会附加到它上

【讨论】:

【参考方案4】:

您要做的是将值作为参数附加到 iframe src (URL) 中。

例如<iframe src="some_page.php?somedata=5&more=bacon"></iframe>

然后在 some_page.php 文件中使用 php $_GET['somedata'] 从 iframe URL 中检索它。注意:iframe 在您的文件中作为单独的浏览器窗口运行。

【讨论】:

【参考方案5】:

我们可以使用“postMessage”概念将数据从主窗口发送到底层 iframe。

you can checkout more about postMessage using this link 在主窗口页面中添加以下代码

// main window code
window.frames['myFrame'].contentWindow.postMessage("Hello World!");

我们将通过“Hello World!”向 iframe id="myFrame" 的 iframe contentWindow 发送消息。

现在在 iframe 源代码中添加以下代码

// iframe document code
function receive(event) 
    console.log("Received Message : " + event.data);

window.addEventListener('message', receive);

在 iframe 网页中,我们将附加一个事件侦听器来接收事件,在“接收”回调中,我们会将数据打印到控制台

【讨论】:

【参考方案6】:

这是另一种解决方案,如果框架来自不同的域,则可以使用。

var frame = /*the iframe DOM object*/;
frame.contentWindow.postMessage(call:'sendValue', value: /*value*/, /*frame domain url or '*'*/);

在框架本身:

window.addEventListener('message', function(event) 
    var origin = event.origin || event.originalEvent.origin; // For Chrome, the origin property is in the event.originalEvent object.
    if (origin !== /*the container's domain url*/)
        return;
    if (typeof event.data == 'object' && event.data.call=='sendValue') 
        // Do something with event.data.value;
    
, false);

但不知道哪些浏览器支持此功能。

【讨论】:

对我来说最好的答案。谢谢! 很有用,虽然我相信 Chrome 的 event.originalEvent.origin 位已经过时了;我在 2019 年 12 月对 Chrome 79 的测试表明它使用了event.origin【参考方案7】:

另外两个选项,它们不是最优雅的,但可能更容易理解和实现,特别是如果 iframe 需要从其父级获取的数据只是几个 var,而不是复杂的对象:

使用 URL 片段标识符 (#)

在容器中:

<iframe name="frame-id" src="http://url_to_iframe#dataToFrame"></iframe>

在 iFrame 中:

<script>
var dataFromDocument = location.hash.replace(/#/, "");
alert(dataFromDocument); //alerts "dataToFrame"
</script>

使用 iFrame 的名称

(我不喜欢这个解决方案 - 它滥用了 name 属性,但它是一个选项,所以我提到它是为了记录)

在容器中:

<iframe name="dataToFrame" src="http://url_to_iframe"></iframe>

在 iFrame 中:

<script type="text/javascript">
alert(window.name); // alerts "dataToFrame"
</script>

【讨论】:

我们不能在 iframe src URL 中使用 URL 参数吗?【参考方案8】:

首先,您需要了解您有两个文档:框架和容器(包含框架)。

从容器操作框架的主要障碍是框架异步加载。您不能简单地随时访问它,您必须知道它何时完成加载。所以你需要一个技巧。通常的解决方案是在框架中使用window.parent 来“向上”(进入包含iframe 标签的文档)。

现在您可以调用容器文档中的任何方法。此方法可以操作框架(例如,使用您需要的参数调用框架中的一些 JavaScript in)。要知道何时调用该方法,您有两种选择:

    从框架的 body.onload 调用它。

    将脚本元素作为最后一件事放入调用容器方法的框架的 HTML 内容中(留给读者作为练习)。

所以框架看起来像这样:

<script>
function init()  window.parent.setUpFrame(); return true; 
function yourMethod(arg)  ... 
</script>
<body onload="init();">...</body>

还有这样的容器:

<script>
function setUpFrame()  
    var frame = window.frames['frame-id'];
    frame.yourMethod('hello');

</script>
<body><iframe name="frame-id" src="..."></iframe></body>

【讨论】:

@testing:当然不是。与浏览器中的其他任何内容一样,它受同源策略的约束。 如果框架是通过它的id 访问的,那么我必须通过contentWindowwindow.frames['frame-id'].contentWindow MDN 中访问它【参考方案9】:

取决于你的具体情况,但如果 iframe 可以在页面的其余部分加载后部署,你可以简单地使用查询字符串,a la:

<iframe src="some_page.html?somedata=5&more=bacon"></iframe>

然后在 some_page.html 的某个地方:

<script>
var params = location.href.split('?')[1].split('&');
data = ;
for (x in params)
 
data[params[x].split('=')[0]] = params[x].split('=')[1];
 
</script>

【讨论】:

伙伴 我要感谢您的回答 - 它解决了一个关键问题!如果您对此问题添加答案,我会将其标记为正确:***.com/questions/2855599/… 对于这个问题,这是最容易实现的答案。我推荐它。 但这受到特定浏览器上 URL 最大长度的限制 :( 最好的部分是:: 它适用于跨域。最适合创建可以在具有不同配置的不同站点中初始化的游戏。很棒的答案。帮了大忙。 当我们的工作很简单时,这是一个很好的解决方案。无需握手通信。【参考方案10】:

使用frames collection。

来自链接:

var frames = window.frames; // or // var frames = window.parent.frames;
for (var i = 0; i < frames.length; i++)  
  // do something with each subframe as frames[i]
  frames[i].document.body.style.background = "red";

如果 iframe 有名称,您还可以执行以下操作:

window.frames['ponies'].number_of_ponies = 7;

只有当这两个页面来自同一个域时,您才能这样做。

【讨论】:

这可以从iframe到不同域的父框架完成吗? 如何在 iframe 中访问number_of_ponies?我觉得我错过了一些明显的东西:/【参考方案11】:

查看下面的链接,它表明可以使用 Javascript 更改页面中 iFrame 的内容,尽管您很可能会遇到一些跨浏览器问题。如果你能做到这一点,你可以使用页面中的 javascript 将隐藏的 dom 元素添加到包含你的值的 iFrame,iFrame 可以读取这些元素。 Accessing the document inside an iFrame

【讨论】:

以上是关于从窗口将值传递给 iframe的主要内容,如果未能解决你的问题,请参考以下文章

如何从rails中的视图将值传递给jquery?

如何在 iOS 中使用 WKWebView 将值动态传递到 iFrame

如何在运行时将值从窗口传递到用户控件?

从 Jquery 将值传递给 href

从按钮将值传递给视图控制器字典

使用jquery在popover上将值传递给iframe