今天学习一个新的window方法:window.postMessage。window.postMessage() 方法可以安全地实现跨源通信。
postMessage是html5引入的API,postMessage()方法允许来自不同源的脚本采用异步方式进行有效的通信,可以实现跨文本文档,多窗口,跨域消息传递.多用于窗口间数据通信,这也使它成为跨域通信的一种有效的解决方案.
之前的一篇iframe高度自适应的文章想必很多人看过,在同源中,处理比较方便,但是对于不同源的iframe处理起来就比较麻烦,需要用到代理页面。而postMessage则直接两个页面交流。
属性详解
postMessage
otherWindow.postMessage(message, targetOrigin, [transfer])
otherWindow
窗口的一个引用,比如iframe的contentWindow属性,执行window.open返回的窗口对象,或者是命名过的或数值索引的window.frames.
message
要发送到其他窗口的数据,它将会被[!结构化克隆算法]
(https://developer.mozilla.org/en-US/docs/DOM/The_structured_clone_algorithm)
序列化.这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化.
targetOrigin
通过窗口的origin属性来指定哪些窗口能接收到消息事件,指定后只有对应origin下的窗口才可以接收到消息,设置为通配符"*"表示可以发送到任何窗口,但通常处于安全性考虑不建议这么做.如果想要发送到与当前窗口同源的窗口,可设置为"/"
transfer | 可选属性
是一串和message同时传递的**Transferable**对象,这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权.
Message事件
window.addEventListener("message", receiveMessage, false) ;
function receiveMessage(event) {
var origin= event.origin;
console.log(event);
}
data 包含任意字符串数据,由原始脚本发送
origin 一个字符串,包含原始文档的方案、域名以及端口(如:http://domain.example:80)
lastEventId 一个字符串,包含了当前的消息事件的唯一标识符。
source 原始文件的窗口的引用。更确切地说,它是一个WindowProxy对象。
ports 一个数组,包含任何MessagePort对象发送消息。
iframe高度自适应
<body>
<h1>父页面</h1>
<iframe src="http://www.szhulian.com/files/childMessage.html" id='myframe' name="myframe" allowTransparency=
"true" scrolling="no" width="100%" height="100%" frameborder="0"></iframe>
<script>
var p = document.getElementById('myframe');
window.postMessage && (window.attachEvent ? window.attachEvent("onmessage",
function(a) {
if (0 === parseInt(a.data, 10)) p.height = "100%",
document.getElementById("myframe").contentWindow.postMessage("getHeight", "*");
else if (a.data.toString().indexOf("px") > 0) {
var b = parseInt(a.data, 10);
isNaN(b) || (p.height = b + "px")
}
}) : window.addEventListener("message",
function(a) {
if (0 === parseInt(a.data, 10)) p.height = "100%",
document.getElementById("myframe").contentWindow.postMessage("getHeight", "*");
else if (a.data.toString().indexOf("px") > 0) {
var b = parseInt(a.data, 10);
isNaN(b) || (p.height = b + "px")
}
},
!1));
</script>
</body>
<body>
<h1>子页面</h1>
<script type="text/javascript">
function calcPageHeight (doc) {
varsHeight = Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight);
return sHeight.toString();
};
calcPageHeight(document);
window.onload = function () {
if (top && top.location !== self.location) {
if ((navigator.appName === 'Microsoft Internet Explorer' && navigator.appVersion .split(';')[1].replace(/[ ]/g, '') === 'MSIE7.0') ||
(navigator.appName === 'Microsoft Internet Explorer' && navigator.appVersion .split(';')[1].replace(/[ ]/g, '') ===
'MSIE6.0')) {
if (top.name) {
top.name = calcPageHeight(document);
}
}
else {
if (top.postMessage) {
window.attachEvent ? window.attachEvent('onmessage', function (event) {
top.postMessage(calcPageHeight(document) + 'px', '*');
}) : window.addEventListener('message', function (event) {
top.postMessage(calcPageHeight(document) + 'px', '*');
}, false);
top.postMessage(0, '*');
}
else if (top.name) {
top.name = calcPageHeight(document);
}
}
}
};
</script>
</body>
深圳 · 龙岗 · 大运软件小镇22栋201
电话:400 182 8580
邮箱:szhulian@qq.com