postMessage+window.name实现iframe跨域通信jquery兼容版

前面的一篇文章我们已经实现了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


关注我

我的微信公众号:前端开发博客,在后台回复以下关键字可以获取资源。

  • 回复「小抄」,领取Vue、JavaScript 和 WebComponent 小抄 PDF
  • 回复「Vue脑图」获取 Vue 相关脑图
  • 回复「思维图」获取 JavaScript 相关思维图
  • 回复「简历」获取简历制作建议
  • 回复「简历模板」获取精选的简历模板
  • 回复「加群」进入500人前端精英群
  • 回复「电子书」下载我整理的大量前端资源,含面试、Vue实战项目、CSS和JavaScript电子书等。
  • 回复「知识点」下载高清JavaScript知识点图谱

每日分享有用的前端开发知识,加我微信:caibaojian89 交流