是的。即使在不同源的情况下,iframe之间仍然可以通过postMessage
API进行通信。postMessage
方法允许来自不同源的脚本采用异步方式进行有限的通信,这对于实现跨域通信非常有用。
基本原理
-
发送消息:使用
window.postMessage
方法从一个窗口向另一个窗口发送消息。消息可以是任何基本类型或可序列化对象(会被转换成字符串)。 -
监听消息:在接收消息的窗口中,使用
window.addEventListener('message', callback)
来监听message
事件。当消息到达时,会触发该事件,回调函数会被执行,并可以访问到发送的消息及发送方的信息。
示例
主页面(parent.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Parent Page</title>
<script>
document.addEventListener('DOMContentLoaded', function() {const iframe = document.getElementById('myIframe');iframe.onload = function() {iframe.contentWindow.postMessage('Hello from Parent', 'https://child.example.com'); // 替换为目标iframe的源};window.addEventListener('message', function(event) {if (event.origin !== 'https://child.example.com') return; // 确认消息来源安全console.log('Received from iframe:', event.data);}, false);
};
</script>
</head>
<body>
<iframe id="myIframe" src="https://child.example.com/child.html"></iframe>
</body>
</html>
iframe页面(child.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Child Iframe</title>
<script>
window.addEventListener('message', function(event) {if (event.origin !== 'https://parent.example.com') return; // 确认消息来源安全console.log('Received from parent:', event.data);event.source.postMessage('Hello from Child', event.origin); // 回复消息给父页面
}, false);
</script>
</head>
<body>
<p>This is the child iframe.</p>
</body>
</html>
请注意,由于浏览器的同源策略限制,必须在发送和接收消息时明确指定targetOrigin
参数,以确保消息只被预期的源接收,从而避免安全风险。上述示例中,通过检查event.origin
来验证消息来源的安全性是十分重要的安全措施。