欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解HTML5 window.postMessage与跨域

程序员文章站 2023-11-23 21:47:52
这篇文章主要介绍了详解HTML5 window.postMessage与跨域,非常具有实用价值,需要的朋友可以参考下... 17-05-11...

在前一篇文章中,讲到浏览器同源策略,即阻止不同域的页面间访问彼此的方法和属性,并对解决同源策略跨域问题提出的解决方案进行阐述:子域代理、jsonp、cors。本篇将详细阐述html5 window.postmessage,借助postmessage api,文档间可以以安全可控的方式实现跨域通信,第三方javascript代码也可以与iframe内加载的外部文档进行通信。

html5 window.postmessage api

html5 window.postmessage是一个安全的、基于事件的消息api。

postmessage发送消息

在需要发送消息的源窗口调用postmessage方法即可发送消息。

源窗口

源窗口可以是全局的window对象,也可以是以下类型的窗口:

文档窗口中的iframe:  

var iframe = document.getelementbyid('my-iframe');
    var win = iframe.documentwindow;

javascript打开的弹窗:  

var win = window.open();

当前文档窗口的父窗口:  

var win = window.parent;

打开当前文档的窗口:  

var win = window.opener();

找到源window对象后,即可调用postmessage api向目标窗口发送消息:

``win.postmessage('hello', 'ttp://jhssdemo.duapp.com/');```

postmessage函数接收两个参数:第一个为将要发送的消息,第二个为源窗口的源。

注:只有当目标窗口的源与postmessage函数中传入的源参数值匹配时,才能接收到消息。

接收postmessage消息

要想接收到之前源窗口通过postmessage发出的消息,只需要在目标窗口注册message事件并绑定事件监听函数,就可以在函数参数中获取消息。

window.onload = function() {
        var text = document.getelementbyid('txt');  
        function receivemsg(e) {
            console.log("got a message!");
            console.log("nmessage: " + e.data);
            console.log("norigin: " + e.origin);
            // console.log("source: " + e.source);
            text.innerhtml = "got a message!<br>" +
                "message: " + e.data +
                "<br>origin: " + e.origin;
        }
        if (window.addeventlistener) {
            //为窗口注册message事件,并绑定监听函数
            window.addeventlistener('message', receivemsg, false);
        }else {
            window.attachevent('message', receivemsg);
        }
    };

message事件监听函数接收一个参数,event对象实例,该对象有三个属性:

  1. data 发送的具体消息
  2. origin 发送消息源
  3. source 发送消息窗口的window对象引用

说明

  1. 可以将postmessage函数第二个参数设为*,在发送跨域消息时会跳过对发送消息的源的检查。
  2. postmessage只能发送字符串信息。

实例

源窗口  

<!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>html5 postmessage</title>
        <style>
            #otherwin {
                width: 600px;
                height: 400px;
                background-color: #cccccc;
            }
        </style>
    </head>
    <body>
        <button id="btn">open</button>
        <button id="send">send</button>
         <!-- 通过 iframe 嵌入子页面(接收消息目标窗口) --> 
         <iframe src="http://jhssdemo.duapp.com/demo/h5_postmessage/win.html" 
                     id="otherwin"></iframe> 
         <br/><br/> 
         <input type="text" id="message"><input type="button" 
                 value="send to child.com" id="sendmessage" /> 
        <script>
            window.onload = function() {
                var btn = document.getelementbyid('btn');
                var btn_send = document.getelementbyid('send');
                var sendbtn = document.getelementbyid('sendmessage');
                var win;
                btn.onclick = function() {
                    //通过window.open打开接收消息目标窗口
                    win = window.open('http://jhssdemo.duapp.com/demo/h5_postmessage/win.html', 'popup');
                }
                btn_send.onclick = function() { 
                    // 通过 postmessage 向子窗口发送数据      
                    win.postmessage('hello', 'http://jhssdemo.duapp.com/');
                }
                function sendit(e){ 
                    // 通过 postmessage 向子窗口发送数据
                    document.getelementbyid("otherwin").contentwindow 
                    .postmessage( 
                        document.getelementbyid("message").value, 
                        "http://jhssdemo.duapp.com/"); 
                } 
                sendbtn.onclick = function(e) {
                    sendit(e);
                };
            };
        </script>
    </body>
    </html>

目标窗口win.html

<!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>html5 postmessage</title>
        <style>
            #txt {
                width: 500px;
                height: 300px;
                background-color: #cccccc;
            }
        </style>
    </head>
    <body>
        <h1>the new window</h1>
        <div id="txt"></div>
        <script>        
            window.onload = function() {
                var text = document.getelementbyid('txt');  
                //监听函数,接收一个参数--event事件对象
                function receivemsg(e) {
                    console.log("got a message!");
                    console.log("nmessage: " + e.data);
                    console.log("norigin: " + e.origin);
                    text.innerhtml = "got a message!<br>" +
                        "message: " + e.data +
                        "<br>origin: " + e.origin;
                }
                if (window.addeventlistener) {
                    //为window注册message事件并绑定监听函数
                    window.addeventlistener('message', receivemsg, false);
                }else {
                    window.attachevent('message', receivemsg);
                }
            };
        </script>
    </body>
    </html>

回顾

通过本篇的学习,了解了使用html5的postmessage api在窗口间进行通信,也知道可以借助其实现跨域通信;现代浏览器基本都支持postmessage,而对于一些老式浏览器如ie7-等,可以使用一定的替代方案,进行数据通信,如window.name、url查询字符和hash片段等。  

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。