首页 » HTML » HTML5 跨文档消息通信

HTML5 跨文档消息通信

HTML5跨文档消息通信(Cross Document Messaging):一种在浏览器跨域窗口间(frames, iframes, popus)进行消息通信的方式。

之所以需要跨域窗口消息通信,主要是因为同源策略的限制。出于安全考虑,浏览器只接收来与当前窗口同源的数据。在HTML5之前,可以通过如jsonp等方式规避同源策略,但有安全隐患。HTML5的跨文档消息通信和XMLHttpRequest Level2则更好的解决了跨源(Cross-origin)的问题。

实践

查看浏览器是否支持:

if(typeof window.postMessage === "undefined") {
    // not support
}

发送端利用window.postMessage()发送消息:

otherWindow.postMessage(message, targetOrigin);

接收端监听消息事件、检查来源,并处理消息:

window.addEventListener("message", msghandler, true);
function msghandler(e) {
    // check e.origin
    // use e.data
}

环境部署

Step1 在服务器上建立两个文档:

  1. portal/portal.html
  2. widget/widget.html

我们将在 portal.html 中用<iframe> 引入 widget.html 文档,并给 widget.html 发送消息。

Step2 运行Python,搭建2个简单的WebServer环境,分别绑定到 9999 和 9998 这两个端口:

$ cd portal && python -m SimpleHTTPServer 9999
$ cd widget && python -m SimpleHTTPServer 9998

Step3 在客户端配置 hosts 文件,添加如:

192.168.1.104 portal.zhuji.com
192.168.1.104 widget.zhuji.com

Step4 在浏览器中输入:

http://portal.zhuji.com:9999/portal.html

如果没有提示错误,基本环境就搭建完毕。

portal.html 文档

portal.html 中用<iframe>引入 widget.html,并给它发送消息(postMessage)。

portal.html 的代码如下:

<!DOCTYPE html>
<html>
    <head>
        <title>portal</title>
    </head>
    <body>
        <p>portal at [http://portal.zhuji.com:9999]</p>
        <iframe src="http://widget.zhuji.com:9998/widget.html" id="widget"></iframe>
        <form id="form">
            <input type="text" id="msg" value="hello widget" />
            <input type="submit" />
        </form>
        <script>
            window.onload = function() {
                var win = document.getElementById("widget").contentWindow;
                document.getElementById("form").onsubmit = function(e) {
                    win.postMessage(document.getElementById("msg").value, "http://widget.zhuji.com:9998");
                    e.preventDefault();
                }
            }
        </script>
    </body>
</html>

widget.html 文档

widget.html 负责接收来自 portal 的消息。接受消息时,判断了消息来源。

widget.html 的代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>widget</title>
    </head>
    <body>
        <p>widget at [http://widget.zhuji.com:9998]</p>
        <div id="rmsg">I'm waiting for msg!</div>
        <script>
            window.addEventListener("message", function(e){
                if(e.origin !== "http://portal.zhuji.com:9999") return;
                document.getElementById("rmsg").textContent = e.origin + " said: " + e.data;
            }, false);
        </script>
    </body>
</html>

分享

0