背景
web端页面加载课件组制作的动画页面,web端需要把参数传递到iframe里面,告诉课件组同学具体加载哪个动画页面。这种情况下很自然想到用iframe方式加载动画页面,然后通过postMessage通信传递参数。
iframe优缺点
- 会阻塞主页面的onload事件
解决方案: 动态生成iframe,在主页面加载完成后去生产iframe加载,从而避免阻塞的影响
- 对SEO不友好
虽然iframe有缺点,但是在某些特定场景下,也可以发挥不错的作用。
postMessage
定义
postMessage() 方法用于安全地实现跨源通信。
语法
otherWindow.postMessage(message, targetOrigin, [transfer]);
用法
标题 | 说明 |
---|---|
otherWindow | 其他窗口的一个引用,比如 iframe 的 contentWindow 属性、执行 window.open 返回的窗口对象、或者是命名过或数值索引的 window.frames。 |
message | 将要发送到其他 window的数据。 |
targetOrigin | 指定哪些窗口能接收到消息事件,其值可以是 *(表示无限制)或者一个 URI。 |
transfer | 可选,是一串和 message 同时传递的 Transferable 对象。这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。 |
示例
主页面代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>主页面</title>
</head>
<body>
<h1>主页面</h1>
<iframe id="child" src="./iframe.html"></iframe>
<div>
<h2>主页面接收消息区域</h2>
<span id="message"></span>
</div>
</body>
<script>
window.onload = function () {
document.getElementById('child').contentWindow.postMessage("我是主页面哦", "http://localhost:5000")
}
window.addEventListener('message', function (event) {
document.getElementById('message').innerHTML = "收到" + event.origin + "消息:" + JSON.stringify(event.data);
}, false);
</script>
</html>
iframe页面代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>子页面</title>
</head>
<body>
<h2>子页面</h2>
<div>
<h3>接收消息区域</h3>
<span id="message"></span>
<button onclick="send()">发送消息</button>
</div>
</body>
<script>
window.addEventListener('message', function (event) {
if (window.parent !== event.source) return
document.getElementById('message').innerHTML = "收到" + event.origin + "消息:" + JSON.stringify(event.data);
}, false);
function send() {
top.postMessage({ type: 'focus' }, "http://localhost:5000")
}
</script>
</html>
演示效果
如果我们把postMessage第二个参数端口改成5001,这时候页面加载完成iframe里面是接收不到主页面发送的消息,点击iframe的按钮也无法发送消息给主页面。