乐闻世界logo
搜索文章和话题

如何从窗口向 iframe 传递值

6 个月前提问
3 个月前修改
浏览次数141

6个答案

1
2
3
4
5
6

在Web开发中,有时我们需要在不同的iframe和父页面(或主窗口)之间传递参数。这可以通过多种方式实现,下面是一些常见的方法:

1. URL参数(查询字符串)

你可以在iframe的src属性中附加查询字符串来传递参数。例如:

html
<iframe src="page.html?param1=value1&param2=value2" ></iframe>

iframe内部的页面page.html中,你可以使用JavaScript来读取URL参数:

javascript
const urlParams = new URLSearchParams(window.location.search); const param1 = urlParams.get('param1'); // value1 const param2 = urlParams.get('param2'); // value2

2. JavaScript postMessage 方法

postMessage方法允许安全地实现跨源通信。父页面可以向iframe发送消息,反之亦然。例如,父页面可以这样发送消息给iframe

javascript
const iframe = document.getElementById('myIframe'); iframe.contentWindow.postMessage('Hello there!', '*');

然后在iframe中监听消息事件:

javascript
window.addEventListener('message', (event) => { // 检查 event.origin 是否是你所期望的源 // if (event.origin !== 'http://example.com') return; console.log('Received message:', event.data); });

3. window.name 属性

window.name属性可以在不同页面之间持久化字符串数据。你可以在加载iframe之前设置它的name属性:

javascript
const iframe = document.createElement('iframe'); iframe.name = JSON.stringify({ param1: 'value1', param2: 'value2' }); document.body.appendChild(iframe); iframe.src = 'page.html';

然后在iframe页面中,可以通过window.name来访问这些参数:

javascript
const params = JSON.parse(window.name);

4. 直接访问iframe的内容

如果iframe是同源的,你可以直接通过JavaScript访问iframe的DOM,并对它进行操作:

javascript
const iframe = document.getElementById('myIframe'); const iframeDocument = iframe.contentDocument || iframe.contentWindow.document; iframeDocument.getElementById('someElement').textContent = '新的文本内容';

示例

假设我们想通过JavaScript postMessage 方法将参数传递给一个iframe。我们可以这样做:

父页面代码:

html
<!DOCTYPE html> <html> <head> <title>Parent Page</title> </head> <body> <iframe id="myIframe" src="iframePage.html" style="height:200px;width:100%;"></iframe> <script> const iframe = document.getElementById('myIframe'); const data = { param1: 'value1', param2: 'value2' }; // 确保iframe完全加载后发送数据 iframe.onload = function() { iframe.contentWindow.postMessage(JSON.stringify(data), '*'); }; </script> </body> </html>

iframe页面代码(iframePage.html):

html
<!DOCTYPE html> <html> <head> <title>Iframe Page</title> </head> <body> <div id="message">Waiting for message...</div> <script> window.addEventListener('message', (event) => { // 这里可以增加对 event.origin 的验证,以确保消息来源的安全性 // if (event.origin !== 'http://example.com') return; const data = JSON.parse(event.data); document.getElementById('message').textContent = 'Received param1: ' + data.param1; }); </script> </body> </html>

在实际应用中,选择哪种方法取决于具体情况,如是否跨域、是否需要双向通信等。使用postMessage时,安全性非常重要,因此一定要验证消息的来源和内容。

2024年6月29日 12:07 回复

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

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

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

shell
<script> var params = location.href.split('?')[1].split('&'); data = {}; for (x in params) { data[params[x].split('=')[0]] = params[x].split('=')[1]; } </script>
2024年6月29日 12:07 回复

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

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

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

  1. 从框架的 body.onload 调用它。

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

所以框架看起来像这样:

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

容器是这样的:

shell
<script> function setUpFrame() { var frame = window.frames['frame-id'].contentWindow; frame.yourMethod('hello'); } </script> <body><iframe name="frame-id" src="..."></iframe></body>
2024年6月29日 12:07 回复

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

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

在框架本身中:

shell
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);

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

2024年6月29日 12:07 回复

还有两个选项,这不是最优雅的,但可能更容易理解和实现,特别是在 iframe 需要从其父级获取的数据只是几个变量而不是复杂对象的情况下:

使用 URL 片段标识符 (#)

在容器中:

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

在 iFrame 中:

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

使用 iFrame 的名称

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

在容器中:

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

在 iFrame 中:

shell
<script type="text/javascript"> alert(window.name); // alerts "dataToFrame" </script>
2024年6月29日 12:07 回复

使用框架集合

从链接:

shell
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 有名称,您还可以执行以下操作:

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

仅当这两个页面由同一域提供时,您才能执行此操作。

2024年6月29日 12:07 回复

你的答案