美文网首页深究JavaScript
messenger.js插件实现html跨域传递数据

messenger.js插件实现html跨域传递数据

作者: zhangweisep | 来源:发表于2020-03-17 15:02 被阅读0次

    messenger.js源码

    /**
     *     __  ___
     *    /  |/  /___   _____ _____ ___   ____   ____ _ ___   _____
     *   / /|_/ // _ \ / ___// ___// _ \ / __ \ / __ `// _ \ / ___/
     *  / /  / //  __/(__  )(__  )/  __// / / // /_/ //  __// /
     * /_/  /_/ \___//____//____/ \___//_/ /_/ \__, / \___//_/
     *                                        /____/
     *
     * @description MessengerJS, a common cross-document communicate solution.
     * @author biqing kwok
     * @version 2.0
     * @license release under MIT license
     */
    
    window.Messenger = (function(){
    
        // 消息前缀, 建议使用自己的项目名, 避免多项目之间的冲突
        // !注意 消息前缀应使用字符串类型
        var prefix = "[PROJECT_NAME]",
            supportPostMessage = 'postMessage' in window;
    
        // Target 类, 消息对象
        function Target(target, name, prefix){
            var errMsg = '';
            if(arguments.length < 2){
                errMsg = 'target error - target and name are both required';
            } else if (typeof target != 'object'){
                errMsg = 'target error - target itself must be window object';
            } else if (typeof name != 'string'){
                errMsg = 'target error - target name must be string type';
            }
            if(errMsg){
                throw new Error(errMsg);
            }
            this.target = target;
            this.name = name;
            this.prefix = prefix;
        }
    
        // 往 target 发送消息, 出于安全考虑, 发送消息会带上前缀
        if ( supportPostMessage ){
            // IE8+ 以及现代浏览器支持
            Target.prototype.send = function(msg){
                this.target.postMessage(this.prefix + '|' + this.name + '__Messenger__' + msg, '*');
            };
        } else {
            // 兼容IE 6/7
            Target.prototype.send = function(msg){
                var targetFunc = window.navigator[this.prefix + this.name];
                if ( typeof targetFunc == 'function' ) {
                    targetFunc(this.prefix + msg, window);
                } else {
                    throw new Error("target callback function is not defined");
                }
            };
        }
    
        // 信使类
        // 创建Messenger实例时指定, 必须指定Messenger的名字, (可选)指定项目名, 以避免Mashup类应用中的冲突
        // !注意: 父子页面中projectName必须保持一致, 否则无法匹配
        function Messenger(messengerName, projectName){
            this.targets = {};
            this.name = messengerName;
            this.listenFunc = [];
            this.prefix = projectName || prefix;
            this.initListen();
        }
    
        // 添加一个消息对象
        Messenger.prototype.addTarget = function(target, name){
            var targetObj = new Target(target, name,  this.prefix);
            this.targets[name] = targetObj;
        };
    
        // 初始化消息监听
        Messenger.prototype.initListen = function(){
            var self = this;
            var generalCallback = function(msg){
                if(typeof msg == 'object' && msg.data){
                    msg = msg.data;
                }
                
                var msgPairs = msg.split('__Messenger__');
                var msg = msgPairs[1];
                var pairs = msgPairs[0].split('|');
                var prefix = pairs[0];
                var name = pairs[1];
    
                for(var i = 0; i < self.listenFunc.length; i++){
                    if (prefix + name === self.prefix + self.name) {
                        self.listenFunc[i](msg);
                    }
                }
            };
            if ( supportPostMessage ){
                if ( 'addEventListener' in document ) {
                    window.addEventListener('message', generalCallback, false);
                } else if ( 'attachEvent' in document ) {
                    window.attachEvent('onmessage', generalCallback);
                }
            } else {
                // 兼容IE 6/7
                window.navigator[this.prefix + this.name] = generalCallback;
            }
        };
    
        // 监听消息
        Messenger.prototype.listen = function(callback){
            var i = 0;
            var len = this.listenFunc.length;
            var cbIsExist = false;
            for (; i < len; i++) {
                if (this.listenFunc[i] == callback) {
                    cbIsExist = true;
                    break;
                }
            }
            if (!cbIsExist) {
                this.listenFunc.push(callback);
            }
        };
        // 注销监听
        Messenger.prototype.clear = function(){
            this.listenFunc = [];
        };
        // 广播消息
        Messenger.prototype.send = function(msg){
            var targets = this.targets,
                target;
            for(target in targets){
                if(targets.hasOwnProperty(target)){
                    targets[target].send(msg);
                }
            }
        };
    
        return Messenger;
    })();
    

    A系统页面推送数据

    /**
     * 选择数据(跨域设置)
     */
    var messenger = new Messenger('index', 'CROSS_DOMAIN_COMMUNICATION');//NEW信使类
    messenger.addTarget(window.parent, 'chartDesign');//创建一个消息对象,设定父级级别
    
    //传递数据
    messenger.targets['chartDesign'].send(JSON.stringify(data));
    

    B系统页面获取数据

    
    let messenger_customflow = new Messenger('chartDesign', 'CROSS_DOMAIN_COMMUNICATION'),
    //获取iframe元素
    custom_Iframe = document.getElementById('custom_Iframe');
    //处理获取的数据
    messenger_customflow.listen(loadCustomData);
    messenger_customflow.addTarget(custom_Iframe, 'index');
    
    /**
    * @param msg 获取的跨域数据
    */
    function loadCustomData(msg){
      console.log(JSON.parse(msg));
      //关闭窗口
      ...
    }
    

    适用于iframe页面,但两个页面存在于不用系统之间的场景。

    相关文章

      网友评论

        本文标题:messenger.js插件实现html跨域传递数据

        本文链接:https://www.haomeiwen.com/subject/fustyhtx.html