• 运用iframe监听消息


    1.跨域的一个示例

    当你需要操作一个内嵌iframe时,如果这个内嵌iframe和打开的网站不在同一个域中,你时常会遇到这样的报错:

    Unsafe JavaScript attempt to access frame with URL http:/www.d1.com from frame with URL http://www.d2.com. Domains, protocols and ports must match.

    从报错信息中我们可以知道,浏览器是通过域名(domain),协议(HTTP),端口(Port)。也就是说这三点只要有一个不匹配那就是跨域(Cross domain)。

    对于跨域,我们通常的解决办法是在原来的域添加一个文件,用该文件作为中间人来实现跨域。也就是说,先发消息到该文件,由该文件再操作同域的HTML。

    HTML 5给我们带来了安全的跨域通信接口,即window.postMessage()方法。它方法原型是:

    window.postMessage(msg, domain);

    我们可以给指定的domain发送msg。而接收msg的iframe只要注册一个监听事件就可以了。我们看示例:

    www.d1.com/a.html

    <html>

      <head>

        <title>operate the iframe on other domain</title>

        <script>

          function sendMessage(){

            var frm = document.getElementByIdx_x_x("iframe1");

            frm.contentWindow.postMessage("hello","*")

          }

        </script>

      </head>

      <body>

        <input id="send" type="button" onclick="sendMessage()" value="send message" />

        <br />

        <iframe style="300px; height:400px;" id="iframe1" src="http://www.d2.com/b.html"></iframe>

      </body>

    </html>

    我们再看看监听的那个iframe

    www.d2.com/b.html

    <html>

      <head>

        <title>a frame which receive the message</title>

        <script>

          var OnMessage = function (e) {

            alert(e.data);

          }

          function init() {

            if (window.addEventListener) {                                    // all browsers except IE before version 9

              window.addEventListener("message", OnMessage, false);

            } else {

              if (window.attachEvent) {                                      // IE before version 9

                window.attachEvent("onmessage", OnMessage);

              }

            }

          }

          init();

        </script>

      </head>

      <body>

        <p>a iframe to receive the message</p>

      </body>

    </html>

    在监听处理函数中我们可以判断具体的那个domain发来的消息。

    注意事项

    如果你在接受消息的iframe中通过JavaScript来修改DOM元素。要确保iframe已经加载完成,可以这样做:

    _overlay = document.getElementByIdx_x_x("iframe1");

    if(_overlay.attachEvent){

      _overlay.attachEvent("onreadystatechange", function(){

        if(_overlay.readyState === "complete" || _overlay.readyState == "loaded"){

          _overlay.detachEvent( "onreadystatechange", arguments.callee);

          sendMessage();

        }

      });

    } else {

      if(_overlay.addEventListener){

         _overlay.addEventListener( "load", function(){

        this.removeEventListener( "load", arguments.call, false);

        sendMessage();

        }, false);

      }

    }

     注意:子框架向父框架发送消息用

    window.parent.postMessage({type: 'IndexBack'}, '*');
    监听消息类似
  • 相关阅读:
    定时刷新
    Codesmith生成oracle、mssql模版中的部分区别和基本功能备忘
    oracle使用中遇到的问题备忘
    存储过程内建临时表和临时函数,合并一个由存储过程返回的表
    烂MP3
    别人笑我太疯癫,我笑别人看不穿
    服务器被挂Iframe木马的解决方法(不是IIS映射修改,也不是ARP病毒,并且网页文件源代码里没有iframe代码的解决方法)
    随便记录下
    重构桌面飘着圣诞老人,利用策略模式和改造的代理模式让软件完全实现开闭原则,欢迎下载源代码分析
    Nhibernate连接oracle数据库报 Could not compile the mapping document异常的解决方法
  • 原文地址:https://www.cnblogs.com/rui00910/p/6907282.html
Copyright © 2020-2023  润新知