前面的一篇文章我们已经实现了postMessage+window.name实现了iframe高度自适应,iframe跨域通信,这篇文章基于jquery,完善了之前文章作者提到的一些不足,一起来看看。
在标准的浏览器上面可以用 postMessage 进行通信,那么在不支持这种方法的低版本 IE 上面就不行了,低版本的 IE 可以使用 window 对象的 name 属性来进行跨域的数据通信。
window.name 在低版本 IE 下面有跨域可以在 iframe 之间互相读取而不受限,所以在低版本 IE 下就能通过 互相重写,读取而进行数据的相互交换,但有个问题就是只能是字符串类型的,可以通过传输 json 对象数据转化来的字符串。
下面就是我自己通过参考一些资料,基于 Jquery 封装的一个兼容版本的跨域 iframe 通信方案
(function() {
var util = {
mix: $.extend,
stringify: JSON.stringify,
parse: JSON.parse
}; // 基础的一些方法
var usePM = ( typeof window.postMessage !== 'undefined'); // 是否支持 postMessage
var PM = function( win ) {
this._win = win;
this._event = function(){};
this._initialize();
};
util.mix( PM.prototype, {
_initialize: function() { // 初始化
var me = this;
if ( usePM ) {
if( window.addEventListener ) {
window.addEventListener('message', function(e){
me._event( util.parse(e.data));
});
} else {
window.attachEvent('onmessage', function(e){
me._event( util.parse(e.data));
});
}
} else {
var lastName = window.name;
setInterval( function() {
if( window.name != lastName && window.name != '' ) {
lastName = window.name;
me._event( util.parse(lastName));
}
}, 50);
}
},
onmessage: function(callback) { // 添加 onmessage 方法
this._event = callback;
},
send: function( data, origin ) { // send 方法
var wl = window.location;
var sendOrigin = wl.href.substr( 0, wl.href.indexOf( wl.pathname ) + 1 );
var sendData = {
data: data,
ts: (+(new Date)).toString(10),
origin: sendOrigin
}
if( usePM ) {
this._win.postMessage( util.stringify(sendData), origin || '*' );
} else {
this._win.name = util.stringify(sendData);
}
}
});
window.XPM = PM;
})();
因为低版本的 IE 不支持 JSON 对象,所以要想使用 JSON.stringify 和 JSON.parse 这两个方法的话需要引用 GitHub 库上的 json2.js 这个兼容文件。
然后,为了考虑低版本 IE 的问题,所以把 postMessage 的 data 又封装了一层,添加了 origin 和 ts(timeStmap) 时间戳,防止消息重复,并且能对消息来源做判断和限制。
使用方法
var f = window.parent;
var PM = new XPM(f);
PM.onmessage(function(e){
alert(e.data);
console.log(e);
});
$('button').bind('click',function(){
var text = "this is a message!";
PM.send(text);
});
演示:iframe高度自适应
原文:https://blog.alphatr.com/iframe-cross-domain.html