• 跨域的N种方法之postMessage


    一、技术背景

      postMessage是html5引入的API可以更方便、有效、安全的解决这些问题。postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。

    二、使用

      otherWindow.postMessage(message, targetOrigin, [transfer])方法接受两个参数

        otherWindow:其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames

        data: html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。
        origin: 协议+主机+端口号,也可以设置为"*",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。

    三、具体实践

      1、A域中的index页面

        ①动态(或者直接在文档内)创建一个iframe标签。src指向数据源(B域index)页面。

        ②ifr加载完成通过ifr.contentWindow属性获取B域中的window对象。然后通过该window对象下的postMessage方法发送数据

        ③第一个参数为要传送的数据,最好为字符串。第二个参数为要发送数据的目标,即数据源。

        ④通过监听window对象的message事件,通过回调函数接收数据源返回的数据。

    <!DOCTYPE html>
    <html>
    <head>
        <title>A域=>postMessage跨域实践</title>
    </head>
    <body>
        <input id="data" type="text" name="" value="">
        <button id="post">点击发送</button>
    </body>
    <script type="text/javascript">
        var ifr = document.createElement("iframe")
            ifr.style.display="none";
            ifr.src="http://top.jiangqi.cn:8081/index3.html"
        post.onclick=function(){
            var data = document.getElementById("data").value;
            document.getElementsByTagName("head")[0].appendChild(ifr);
            ifr.onload = function(){
                ifr.contentWindow.postMessage(JSON.stringify(data),"http://top.jiangqi.cn:8081/index3.html")
            }
        }
        window.addEventListener("message",function(e){
         console.log(e) console.log(e.data) },
    false) </script> </html>

      2、B域中的index页面:

        ①通过监听window的message消息,回调接收A域传过来的参数。

        ②window.parent获取父窗口的引用。然后通过postMessage返回数据给A域

    <!DOCTYPE html>
    <html>
    <head>
        <title>B域=>postMessage跨域实践</title>
    </head>
    <body>
    
    </body>
    <script type="text/javascript">
        window.addEventListener("message",function(e){
            if(JSON.parse(e.data)){
                window.parent.postMessage("我已经收到data:"+e.data,"http://www.jiangqi.cn/index3.html")
            }
        },false)
    </script>
    </html>

    四、使用注意事项

      1、用于接收消息的任何事件监听器必须首先使用origin和source属性来检查消息的发送者的身份。 这不能低估:无法检查origin和source属性会导致跨站点脚本攻击。

      2、其他安全问题(见参考)

    五、参考

      1、https://www.secpulse.com/archives/56637.html

      2、https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage

  • 相关阅读:
    CodeForces666E Forensic Examination
    #46. 【清华集训2014】玄学
    #207. 共价大爷游长沙
    BZOJ4259残缺的字符串
    [六省联考2017]分手是祝愿
    BZOJ2616PERIODNI
    UVa 1363 Joseph's Problem (等差数列)
    UVa 1641 ASCII Area
    UVa 10213 How Many Pieces of Land? (组合数学 & 图论)
    UVa 1640 The Counting Problem (数位DP)
  • 原文地址:https://www.cnblogs.com/helloNico/p/10647419.html
Copyright © 2020-2023  润新知