postMessage跨域实现localstorage跨域共享 浅谈postMessage跨域通讯与localStorage实现跨域共享

浅谈postMessage跨域通讯与localStorage实现跨域共享

咱们可能有须要在多个域名之间共用同一个localStorage的须要javascript

1、咱们先测试不一样域名之间的通讯css

  1.有 child.html 以下,代码中 window.parent.postMessage(data,origin) 方法容许来自不一样源的脚本采用异步方式进行通讯,能够实现跨文本档、多窗口、跨域消息传递。接受两个参数:html

  • data:要传递的数据,html5规范中提到该参数能够是JavaScript的任意基本类型或可复制的对象,然而并非全部浏览器支持任意类型的参数,部分浏览器只能处理字符串参数,因此在传递参数时须要使用JSON.stringify()方法对对象参数序列化。
  • origin:字符串参数,指明目标窗口的源,协议+主机+端口号[+URL],URL会被忽略,因此能够不写,只是为了安全考虑,postMessage()方法只会将message传递给指定窗口,固然也能够将参数设置为"*",这样能够传递给任意窗口,若是要指定和当前窗口同源的话设置为"/"。
复制代码
<!doctype html>  
<html>  
    <head>  
        <style type="text/css">  
            html,body{  
                height:100%;  
                margin:0px;  
            }  
        </style>  
    </head>  
    <body style="height:100%;">  
        <div id="container" onclick="changeColor();" style="widht:100%; height:100%; ">  
            click to change color  
        </div>  
        <script type="text/javascript">  
            var container = document.getElementById('container');  
            // iframe接收消息,并把当前颜色发送给主页面  
            changeColor();
            // 点击iframe时触发changeColor方法,把变化后的颜色发送给主页面  
            function changeColor() {       
                var color = container.style.backgroundColor;  
                if (color == 'rgb(204, 102, 0)')  
                    color = 'rgb(204, 204, 0)';  
                else  
                    color = 'rgb(204,102,0)';  
                container.style.backgroundColor = color;
                console.log('start post color ..............');
                window.parent.postMessage(color, '*');  
            }  
        </script>  
    </body>
</html>
复制代码

 

  2.而后在 main.html 中引入 child.html,window.addEventListener('message', function(e) { dosomething....}, false);  用来监听iframe 中发过来的消息html5

复制代码
<!DOCTYPE html>    
<html>    
    <head>    
        <title></title>    
    </head>    
    <body>    
        <div style="width:200px; float:left; margin-right:200px;border:solid 1px #333;">    
            <div id="color">Frame Color</div>    
            </div>    
        <div>    
        <iframe id="child" src="http://www.abc.com/child.html"></iframe>    
        </div>    
        <script type="text/javascript">       
            // 主页面监听message事件,初始化自身颜色  
            // 主页面监听message事件,处理自身变色  
            window.addEventListener('message', function(e) {
                console.log('listen.....');
                var color = e.data;    
                document.getElementById('color').style.backgroundColor = color;    
            }, false);    
        </script>    
    </body>    
</html>  
复制代码

 

  3.这时咱们就能够看到效果了,以下图,当咱们点击包含在main.html 中的 child.html页面时,main.html中的FrameColor也跟着变了java

 2、接下来咱们实现跨域之间的localstorage共享 跨域

  1.解决思路:在A域和B域下引入C域,全部的读写都由C域来完成,本地数据存在C域下; 所以 A哉和B域的页面一定要引入C域的页面; 固然C域最好是主域,缘由后面会提到(在localstorage 不方便的状况下使用cookie);浏览器

  • 【A域】【B域】须要读写时,经过postMessage 向【C域】发送跨哉消息,
  • 【C域】监听跨域消息,在接到批定的消息时进行读写操做,
  • 【C域】接到跨域消息时,若是是写入删除能够不作什么,若是是读取,就要先读取本域本地数据经过postMessage向父页面发送消息,
  • 【A 域 / B 域】在读取【C域】数据时就须要监听来自【C域】的跨域消息

  

  2.注意事项:安全

  window.postMessage()方法,向【C域】发消息,应用iframe.contentWindow.postMessage() 这样iframe内的【C 域】才能够接到,cookie

  同理,【C域】向 【A 域B域】发消息时应用,window.parent.postMessage(),【A域、B域】的逻辑必定要在iframe 加载完成后进行。dom

 

  3.代码:

   【C域】页面以下:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="robots" content="noindex">
    <title>cross domain</title>
</head>
<body>
<script>
  ;(function(doc,win,undefined){
      var fn=function(){};
      fn.prototype={
          /*本地数据存储*/
          setLocalCookie: function (k, v, t,domain) {
              typeof window.localStorage !== "undefined" ? localStorage.setItem(k, v) :
                      (function () {
                          t = t || 365 * 12 * 60 * 60;
                          domain=domain?domain:".hc360.com";
                          document.cookie = k + "=" + v + ";max-age=" + t+";domain="+domain+";path=/";
                      })()
          },
          getLocalCookie: function (k) {
              k = k || "localDataTemp";
              return typeof window.localStorage !== "undefined" ? localStorage.getItem(k) :
                      (function () {
                          var all = document.cookie.split(";");
                          var cookieData = {};
                          for (var i = 0, l = all.length; i < l; i++) {
                              var p = all[i].indexOf("=");
                              var dataName = all[i].substring(0, p).replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");
                              cookieData[dataName] = all[i].substring(p + 1);
                          }
                          return cookieData[k]
                      })();
          },
          clearLocalData: function (k) {
              k = k || "localDataTemp";
              typeof window.localStorage !== "undefined" ? localStorage.removeItem(k) :
                      (function () {
                          document.cookie = k + "=temp" + ";max-age=0";
                      })()
          },
          init:function(){
              this.bindEvent();
          },
          bindEvent:function(){
              var _this=this;
              win.addEventListener("message",function(evt){
                  if(win.parent!=evt.source){return}
                  var options=JSON.parse(evt.data);
                  if(options.type=="GET"){
                      var data=tools.getLocalCookie(options.key);
                      win.parent.postMessage(data, "*");
                  }
                  options.type=="SET"&&_this.setLocalCookie(options.key,options.value);
                  options.type=="REM"&&_this.clearLocalData(options.key);
              },false)
          }
      };
      var tools=new fn();
      tools.init();
  })(document,window);
</script>
</body>
</html>
复制代码

  【A域】页面以下:咱们再C中设置了 localStorage

复制代码
<!DOCTYPE html>    
<html>    
    <head>    
        <title></title>    
    </head>    
    <body>    
        <div style="width:200px; float:left; margin-right:200px;border:solid 1px #333;">    
            <div id="color">Frame Color</div>    
            </div>    
        <div>    
        <iframe id="child" src="http:///c.html"></iframe>    
        </div>    
        <script type="text/javascript">   
            window.onload = function() {
                console.log('set key value......................')
                window.frames[0].postMessage(JSON.stringify({type:"SET",key:"key",value:"value"}),'*');
            }          
        </script>    
    </body>    
</html>  
复制代码

上传A、C以后咱们见到效果如上图

 

    【B域】页面以下:咱们读取A中设置的 localStorage

复制代码
<!DOCTYPE html>    
<html>    
    <head>    
        <title></title>    
    </head>    
    <body>    
        <div style="width:200px; float:left; margin-right:200px;border:solid 1px #333;">    
            <div id="color">Frame Color</div>    
            </div>    
        <div>    
        <iframe id="child" src="http:///c.html"></iframe>    
        </div>    
        <script type="text/javascript">   
            window.onload = function() {
                console.log('get key value......................')
                window.frames[0].postMessage(JSON.stringify({type:"GET",key:"key"}),'*');
            }
            window.addEventListener('message', function(e) {
                console.log('listen.....');
                var data = e.data;    
                console.log(data);
            }, false);
        </script>    
    </body>    
</html>  
复制代码

访问c打开console见到效果以下 

至此咱们实现了跨域 localStorage 的读取和删除。

相关文章
相关标签/搜索