iframe使用记录
iframe使用记录
iframe通讯
在不同域名下的 <iframe> 通讯(即跨域通信)会面临浏览器的同源策略限制。同源策略规定,只有当页面和iframe的内容来自相同的源(协议、域名、端口完全一致)时,它们才可以直接互相访问和操作。
为了实现跨域通信(即不同域名下的iframe之间的通信),通常有以下几种方法:
1. postMessage 方法
postMessage 是一种安全的跨文档消息传递机制,可以在不同源之间发送消息。它允许来自不同源的窗口(如父窗口和iframe)进行通信。
使用 postMessage 实现跨域通信
1.1 父页面发送消息到 iframe
假设父页面和 iframe 位于不同的域,父页面可以通过 postMessage 向 iframe 发送消息。
// 父页面的代码 (parent.html)
var iframe = document.getElementById('myIframe');
// 向 iframe 发送消息
iframe.contentWindow.postMessage('Hello from parent', 'https://iframe-domain.com');
需要注意的是,上面中https://iframe-domain.com 如果没有放开443端口,则域名使用需要加上端口
例如:
<iframe allow="camera; microphone; fullscreen; display-capture; autoplay"
src="https://iframe-domain.com:3030/voice/1" style="border: 0px;position: absolute;top: 100px;left: 0;"></iframe>
则使用postMessage iframe.contentWindow.postMessage('Hello from parent', 'https://iframe-domain.com:3030');
1.2 iframe 接收父页面的消息
iframe 页面可以通过 window.addEventListener 来监听来自父页面的消息。
// iframe 页面 (iframe.html)
window.addEventListener('message', function(event) {
// 检查消息来源
if (event.origin !== 'https://parent-domain.com') {
return; // 安全性:只接受来自指定域的消息
}
console.log('Received message:', event.data);
});
1.3 iframe 发送消息给父页面
同样,iframe 也可以向父页面发送消息:
// iframe 页面 (iframe.html)
window.parent.postMessage('Hello from iframe', 'https://parent-domain.com');
1.4 父页面接收 iframe 的消息
父页面监听来自 iframe 的消息:
// 父页面 (parent.html)
window.addEventListener('message', function(event) {
// 检查消息来源
if (event.origin !== 'https://iframe-domain.com') {
return; // 安全性:只接受来自指定域的消息
}
console.log('Received message from iframe:', event.data);
});
关键点:
postMessage安全性:每次接收消息时,应验证消息的来源(event.origin),确保只处理来自受信任源的消息。targetOrigin参数:postMessage的第二个参数是目标源(targetOrigin),它可以确保消息只发送到指定的源。这是一个安全防范措施。- 示例:
iframe.contentWindow.postMessage(message, 'https://iframe-domain.com')
- 示例:
2. window.name 作为跨域传递数据的技巧
window.name 是一种比较古老的跨域通信技巧,利用 window.name 属性的特点,在不同域之间传递数据。这种方法通常需要通过重定向跳转到同一页面并回传数据。
示例:
- 父页面在不同域上创建一个
iframe并加载目标页面。 iframe页面通过修改window.name来传递数据。- 父页面监视
iframe的window.name来获取数据。
不过,这种方法已不再推荐,因为它比较复杂,且浏览器实现和安全性都可能带来一些问题。
3. JSONP(不推荐)
JSONP 是早期为了解决跨域问题而出现的一个技巧,但由于它只能用于 GET 请求,且存在安全风险,通常不再推荐使用。
4. CORS(跨域资源共享)
虽然 postMessage 解决了浏览器间的消息传递问题,CORS 主要是用于解决跨域的资源请求(如通过 AJAX 获取外部 API 或资源)。它不适用于 iframe 之间的直接消息传递。
但是,如果你需要从父页面加载外部域的资源或与外部 API 进行交互,你可以使用 CORS 来配置允许跨域请求。
// 父页面通过 Ajax 请求跨域资源,CORS 配置在服务器端设置
fetch('https://iframe-domain.com/api/data', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
5. 服务器中转
如果跨域通信存在严格的安全限制,可以通过服务器中转的方式来实现跨域数据交换。父页面和 iframe 都与服务器进行通信,服务器将数据转发给对方。
示例:
- 父页面通过
AJAX请求与服务器通信。 iframe页面也通过AJAX请求与服务器通信。- 服务器根据需要转发信息给双方。
总结
- 最推荐的方法是
postMessage,它提供了一种安全且简单的跨域通信方式,支持不同域之间的iframe和父页面的双向通信。 - 跨域请求(如获取资源)通常通过 CORS 配置来实现,但 CORS 并不适用于
iframe之间的直接消息传递。 - 使用
postMessage时,要特别注意消息的来源和目标,确保不会受到跨站脚本攻击(XSS)的风险。
如果你有更具体的需求,或者想了解其他方法,随时可以继续提问!
其他
keep-alive缓存不了iframe