从窗口将值传递给 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
访问的,那么我必须通过contentWindow
在window.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的主要内容,如果未能解决你的问题,请参考以下文章