咱们都知道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...