咱們可能有須要在多個域名之間共用同一個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 的讀取和刪除。