概述
window.postMessage()方法安全地启用Window对象之间的跨源通信
提供了一种受控机制来规避同源策略的限制
兼容性:
![](https://img.haomeiwen.com/i13748290/20276e16808358b9.png)
语法格式:
【发送数据语法】
targetWindow.postMessage(message,targetOrigin,[ transfer ])
参数信息:
- targetWindow:
iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames - message:
将要发送到其他 window的数据(它将会被结构化克隆算法序列化,保证数据安全) - targetOrigin:
如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的targetOrigin,而不是*。
不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点 - transfer:
是一串和message 同时传递的 Transferable 对象.
这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权
【接收数据语法】
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event){
var origin = event.origin || event.originalEvent.origin;
if(origin !== "http://www.aaa.com:8080"){ return;}
console.log(event.data)
}
参数信息:
- event.data
从其他 window 中传递过来的对象 - origin
调用 postMessage 时消息发送方窗口的 origin
这个字符串由 协议、“://“、域名、“ : 端口号”拼接而成
【注】: 这个origin不能保证是该窗口的当前或未来origin,因为postMessage被调用后可能被导航到不同的位置。 - event.source
对发送消息的窗口对象的引用
实例
情景,主页面嵌套了一个非同源的iframe,且需要进行数据交互
主页面域名 http://www.a.com
iframe嵌套域名 http://www.b.com
主页面:源信息(http://localhost)
//iframe内嵌页面的(源 协议、IP地址、端口号)
var iframeOrigin = 'http://106.x.x.4:8099';
//--显示支付
var _gameOptionsBox = $('#gameOptionsBox');
var _payFrameBox = $('#payFrameBox');
//iframe元素
var _oF = $('#payFrame').get(0);
//传递的信息
var _mes = '传递子iframe的信息';
$('#showPayPopBtn').bind('click',function(){
$('#payFrame').attr('src',(iframeOrigin+'/gamebox/pay.html?goodsName=110元宝&goodsPay=280.00'));
_gameOptionsBox.hide();
_payFrameBox.show();
_oF.onload = function(){
//iframe跨域 发送信息
_oF.contentWindow.postMessage(_mes,iframeOrigin);
}
});
//iframe跨域 接收信息
window.addEventListener("message", receiveMessage, false);
function receiveMessage(ev){
//筛选信任接收源
if(ev.origin == iframeOrigin){
//console.log('正确源')
if(ev.data){
var _tagN = ev.data.tagN;
var _payWay = ev.data.payWay;
alert('支付方式 '+_payWay);
$(document.getElementById(_tagN)).slideUp(300);
}
}else{
console.log('发送源不可信');
return;
}
}
iframe页面内 源信息(http://106.x.x.4:8099)
//接收iframe postMessage跨域信息
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event){
//信息发起源
var frameBoxOrigin = event.origin || event.originalEvent.origin;
var frameBoxSource = event.source;
//不是发送源直接返回
if(frameBoxOrigin!='http://localhost'){
console.log('发送源不可信');
return;
}
//iframe内关闭按钮
$('#closeFrameBtn').on('click',function(){
//传递到iframe父级的信息
var returnData = {'tagN':'payFrameBox','payWay':'微信支付'};
frameBoxSource.postMessage(returnData,frameBoxOrigin);
});
}
备注
onmessage接收信息的时候
- 需要确定发送源是否是安全的,因为postMessage被调用后可能被导航到不同的位置
- event.origin存在兼容性问题(For Chrome, the origin property is in the event.originalEvent object.)
网友评论