跨域 Iframe 通信解决方案(兼容 IE 系列浏览器。)

实现思路:

     1、postMessage(IE8+, Firefox 3.1+, Opera 9+, Safari, and Chrome)

     2、利用window.navigator共享信息,使支持IE6,IE7

                i、父窗口向子窗口iframe发送信息:

               document.getElementById("childiframe").contentWindow .postMessage(

                   "我是父窗口",

                   "http://child.com:8080"   //可以*通配符代替,表示支持所有域

               ); 

                       上面的代码表示父窗口向子iframe:childiframe,域名为"http://child.com:8080"  发送 "我是父窗口"的消息

 

                 ii、子iframe

               window.addEventListener("message", function( event ) { 

		      // 把父窗口发送过来的数据显示在子窗口中

	             document.getElementById("content").innerHTML+=event.data+"<br/>"; 

	       }, false ); 

                  iii、父窗口如果有多个子iframe,那么父窗口可以向多个子窗口发送消息

                        利用Object-orient-programing  ,父窗口和多个子窗口分别实例化一个Message对象,各个窗口的message对象里开辟一个内存可以保存多个目标对象Target,意思是要发送消息到这些目标,

                         Target对象实现自己的send方法 ,send考虑到浏览器的兼容性,Target对象里保存了target和name信息,target表示要发送的窗口,name是发送目标的名称 ,name的作用仅仅是支持IE6、7中使用到(在window.navigator标示一个唯一send的回调函数)   

     var prefix = "arale-messenger",
        supportPostMessage = 'postMessage' in window;
// Target 类, 消息对象 function Target(target, name){ 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; } // 往 target 发送消息, 出于安全考虑, 发送消息会带上前缀 if ( supportPostMessage ){ // IE8+ 以及现代浏览器支持 Target.prototype.send = function(msg){ this.target.postMessage(prefix + msg, '*'); }; } else { // 兼容IE 6/7 利用window.navigator共享信息,使支持IE6,IE7 Target.prototype.send = function(msg){ var targetFunc = window.navigator[prefix + this.name]; if ( typeof targetFunc == 'function' ) { targetFunc(prefix + msg, window); } else { throw new Error("target callback function is not defined"); } }; }

              iiii: 每个窗口都实例化的Message类:

                targets 里保存目标发送对象,name当前窗口的名字,最后会传给Target,也是只在兼容IE6、7中用到。

                listenFunc :保存监听的回调,一个页面可以实现多个监听。

                initListen :ie6、7中保存全局回调函数,以方便在Target的send中触发

                                IE8+和现代化浏览器中监听message事件。

    // 信使类

    // 创建Messenger实例时指定, 必须指定Messenger的名字, (可选)指定项目名, 以避免Mashup类应用中的冲突

    // !注意: 父子页面中projectName必须保持一致, 否则无法匹配

    function Messenger(messengerName, projectName){

        this.targets = {};

        this.name = messengerName;

        this.listenFunc = [];

        prefix = projectName || prefix;

        this.initListen();

    }



    // 添加一个消息对象

    Messenger.prototype.addTarget = function(target, name){

        var targetObj = new Target(target, name);

        this.targets[name] = targetObj;

    };



    // 初始化消息监听

    Messenger.prototype.initListen = function(){

        var self = this;

        var generalCallback = function(msg){

            if(typeof msg == 'object' && msg.data){

                msg = msg.data;

            }

            // 剥离消息前缀

            msg = msg.slice(prefix.length);

            for(var i = 0; i < self.listenFunc.length; i++){

                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[prefix + this.name] = generalCallback;

        }

    };



    // 监听消息

    Messenger.prototype.listen = function(callback){

        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);

            }

        }

    };

 

    完整demo:

    跨域 Iframe 通信解决方案(兼容 IE 系列浏览器。)

     完整代码:

     message.js

(function(w){

    // 消息前缀, 建议使用自己的项目名, 避免多项目之间的冲突

    var prefix = "arale-messenger",

        supportPostMessage = 'postMessage' in window;



    // Target 类, 消息对象

    function Target(target, name){

        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;

    }



    // 往 target 发送消息, 出于安全考虑, 发送消息会带上前缀

    if ( supportPostMessage ){

        // IE8+ 以及现代浏览器支持

        Target.prototype.send = function(msg){

            this.target.postMessage(prefix + msg, '*');

        };

    } else {

        // 兼容IE 6/7

        Target.prototype.send = function(msg){

            var targetFunc = window.navigator[prefix + this.name];

            if ( typeof targetFunc == 'function' ) {

                targetFunc(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 = [];

        prefix = projectName || prefix;

        this.initListen();

    }



    // 添加一个消息对象

    Messenger.prototype.addTarget = function(target, name){

        var targetObj = new Target(target, name);

        this.targets[name] = targetObj;

    };



    // 初始化消息监听

    Messenger.prototype.initListen = function(){

        var self = this;

        var generalCallback = function(msg){

            if(typeof msg == 'object' && msg.data){

                msg = msg.data;

            }

            // 剥离消息前缀

            msg = msg.slice(prefix.length);

            for(var i = 0; i < self.listenFunc.length; i++){

                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[prefix + this.name] = generalCallback;

        }

    };



    // 监听消息

    Messenger.prototype.listen = function(callback){

        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);

            }

        }

    };



    w["Messenger"]=Messenger;

})(window);

 child.html:

<!doctype html>

<html>

  <head>

    <script type="text/javascript" src="message.js"></script>

    <script>

	window.onload=function(){

	    var messenger = new Messenger('iframe1', 'MessengerProject');

		messenger.addTarget(window.parent, 'parent');

        messenger.targets['parent'].send('发给父页面的消息');

		messenger.listen(function(msg) {

		    document.getElementById("msg").innerHTML=msg;

		});

    }

	</script>

  </head>

  <body>

      child

	  <div id="msg"></div>

  </body>

</html> 

 parent.html

<!doctype html>

<html>

  <head>

    <script type="text/javascript" src="message.js"></script>

	<script>

	window.onload=function(){

	    var messenger = new Messenger('parent', 'MessengerProject');

		var iframe1=window.iframe1;

		messenger.addTarget(iframe1.contentWindow, 'iframe1');

		messenger.targets['iframe1'].send('发给子页面1的消息');

		messenger.listen(function(msg) {

			document.getElementById("msg").innerHTML=msg;

		});

    }

	</script>

  </head>

  <body>

      parent

	  	  <div id="msg"></div>

	  <iframe id="iframe1" src="child.html" width=100 height=100>

  </body>

</html> 

 

你可能感兴趣的:(iframe)