咱們都知道localStorage最大容量是5M,若是咱們要存的數據超過5M了該怎麼辦呢?html
其實,localStorage最大容量5M的意思是每個域名下的localStorage容量是5M,假如如今a.com域名下localstorage存不下了,咱們可使用iframe建立b.com域框架(子頁面)用於存儲a.com剩下的數據。而後使用postMessage讀寫數據。算法
window.postMessage() 方法能夠安全地實現跨源通訊。一般,對於兩個不一樣頁面的腳本,只有當執行它們的頁面位於具備相同的協議(一般爲https),端口號(443爲https的默認值),以及主機 (兩個頁面的模數Document.domain
設置爲相同的值) 時,這兩個腳本才能相互通訊。window.postMessage() 方法提供了一種受控機制來規避此限制,只要正確的使用,這種方法就很安全。segmentfault
otherWindow.postMessage(message, targetOrigin, \[transfer\]);
otherWindow
跨域
其餘窗口的一個引用,好比iframe的contentWindow屬性、執行window.open返回的窗口對象、或者是命名過或數值索引的window.frames。安全
message
cookie
將要發送到其餘 window的數據。它將會被結構化克隆算法序列化。這意味着你能夠不受什麼限制的將數據對象安全的傳送給目標窗口而無需本身序列化。[1]框架
targetOrigin
dom
經過窗口的origin屬性來指定哪些窗口能接收到消息事件,其值能夠是字符串"*"(表示無限制)或者一個URI。在發送消息的時候,若是目標窗口的協議、主機地址或端口這三者的任意一項不匹配targetOrigin提供的值,那麼消息就不會被髮送;只有三者徹底匹配,消息纔會被髮送。這個機制用來控制消息能夠發送到哪些窗口;例如,當用postMessage傳送密碼時,這個參數就顯得尤其重要,必須保證它的值與這條包含密碼的信息的預期接受者的origin屬性徹底一致,來防止密碼被惡意的第三方截獲。若是你明確的知道消息應該發送到哪一個窗口,那麼請始終提供一個有確切值的targetOrigin,而不是*。不提供確切的目標將致使數據泄露到任何對數據感興趣的惡意站點。post
_**transfer**_
可選this
是一串和message 同時傳遞的 Transferable
對象. 這些對象的全部權將被轉移給消息的接收方,而發送一方將再也不保有全部權。
這裏使用http-server來建立兩個不一樣源的本地服務
// http://127.0.0.1:8080 發送方 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <iframe src="http://127.0.0.1:8081/C.html" id="ifr1" frameborder="0" scrolling="no"></iframe> <button onclick="setLocalStorage()">set</button> <button onclick="getLocalStorage()">get</button> <button onclick="removeLocalStorage()">remove</button> </body> </html> <script> var iframeDOM = document.getElementById("ifr1") // iframe加載完畢後再發送消息,不然子頁面接收不到message // iframeDOM.onload = function () { // } // 將 localStorage 存儲到 iframe 中 function setLocalStorage() { iframeDOM.contentWindow.postMessage(JSON.stringify({ type: "SET", key: "key", value: "value" }), '*'); } // 獲取 iframe 中的localStorage function getLocalStorage() { window.addEventListener('message', function (event) { if (iframeDOM.contentWindow != event.source) { return } console.log('post', event) }, false) iframeDOM.contentWindow.postMessage(JSON.stringify({ type: "GET", key: "key" }), '*'); } // 刪除 iframe 中的 localstorage function removeLocalStorage() { iframeDOM.contentWindow.postMessage(JSON.stringify({ type: "REM", key: "key" }), '*'); } </script>
// http://127.0.0.1:8081 接收方 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> </body> </html> <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 : ".zss.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 (event) { if (win.parent != event.source) { return } var options = JSON.parse(event.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>
參考:
https://developer.mozilla.org...
https://segmentfault.com/q/10...
https://blog.csdn.net/sflf369...
https://juejin.im/post/590c39...