iframe之间的通信
·
Yin灏
前言
接下来我们就一起来学习一下关于 iframe
通信的相关知识吧 😁
iframe 通信的几种方式 😶🌫️😶🌫️
1. URL 传参 ✨✨
父窗口可以通过在 iframe 的 src 属性后添加参数来向子窗口传递数据,子窗口可以通过 location.search
或 location.hash
来获取参数。
- 使用
?
拼接参数,子页面使用location.search
接收参数
<!-- parent.html -->
<iframe
id="iframe1"
src="./child1.html?name=来自parent的消息"
frameborder="0"
></iframe>
<!-- child1.html -->
<script>
console.log(window.decodeURIComponent(location.search)); // ?name=来自parent的消息
</script>
- 使用
#
拼接参数,子页面使用location.hash
接收参数,同时还可以使用window.onhashchange
来监听参数的变化。
<!-- parent.html -->
<iframe
id="iframe1"
src="./child1.html#name=来自parent的消息"
frameborder="0"
></iframe>
<script>
const iframe1 = document.getElementById("iframe1");
// 在2s后更改hash
setTimeout(() => {
iframe1.src = "./child1.html#age=12";
}, 2000);
</script>
<!-- child1.html -->
<script>
console.log("hash", window.decodeURIComponent(location.hash)); // #name=来自parent的消息
window.onhashchange = () => {
console.log("hashchange", window.location.hash); // #age=12
};
</script>
⚡⚡ 需要注意的是通过
URL 传参
的时候,传输携带中文的话,记得使用decodeURIComponent
进行解码。
2. window.postMessage✨✨✨✨✨
安全、可靠且支持跨域的 iframe 通信方式,它可以在两个窗口之间异步传递消息。
- 在发送方中,使用
window.postMessage()
方法向另一个窗口发送消息。该方法接收两个参数:要发送的消息和目标窗口的源(例如,"http://127.0.0.1:5500/child.html"
或"*"
)。
window.postMessage("Hello world!", "http://127.0.0.1:5500/child.html");
- 在接收方中,使用
window.addEventListener()
方法监听message
事件。该事件对象包含三个属性:data
表示接收到的数据,origin
表示发送方的源,source
表示发送方窗口的引用。
window.addEventListener("message", function (event) {
// 判断消息是否来自可信任的源
if (event.origin === "http://127.0.0.1:5500/child.html") {
console.log("message: " + event.data);
}
});
兼容性,来自 window.postMessage | MDN
3. window.name✨✨
可以使用一个隐藏的 iframe 和 window.name 属性在不同的窗口之间共享数据。
- 在子页面中,将要传递给父页面的数据保存在
window.name
属性中。
例如
window.name = "Hello Parent!";
- 在父页面中,创建一个隐藏的 iframe 元素,并且将其源设置为
子页面的 URL
。
const iframe = document.createElement("iframe");
iframe.style.display = "none";
iframe.src = "http://127.0.0.1:5500/child1.html";
document.body.appendChild(iframe);
- 在父页面中,等待 iframe 加载完成后,通过访问
iframe.contentWindow.name
属性来获取子页面中保存的数据。
iframe.onload = function () {
const childData = iframe.contentWindow.name;
onsole.log("message:", childData); // 输出:message: Hello Parent!
};
⚡⚡ 注意:使用
window.name
进行跨域 iframe 通信存在安全性问题,因为所有具有相同名称的窗口都可以访问和修改window.name
。
4. 服务器端转发 ✨✨✨
可以将消息从一个 iframe 发送到服务器,然后再由服务器将其转发到另一个 iframe。