前面的一篇文章我们已经实现了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);});
原文:https://blog.alphatr.com/iframe-cross-domain.html