先來幾道面試題
1、a.meituan.com 和 b.meituan.com 這兩個域能夠共享同一個 localStorage 嗎?
2、在 webview 中打開一個頁面:i.meituan.com/home.html,點擊一個按鈕,調用 js 橋打開一個新的 webview:i.meituan.com/list.html,這兩個分屬不同 webview 的頁面能共享同一個 localStorage 嗎?
3、如果 localStorage 存滿了,再往里存東西,或者要存的東西超過了剩余容量,會發生什么?
答案
1、同一個域名(document.domain)共享同一個 localStorage,a.meituan.com 和 b.meituan.com 是兩個域名,所以不能共享
2、能。相當於同一個瀏覽器的不同標簽頁。不同瀏覽器之間不能共享。
3、存不進去並報錯(QuotaExceededError)
理想的方案
假設我們回到起點,從零建設前端工程,我們怎么避免 localStorage 存滿的問題?
1、划分域名。各域名下的存儲空間由各業務組統一規划使用
2、跨頁面傳數據:考慮單頁應用、優先采用 url 傳數據
3、最后的兜底方案:清掉別人的存儲
互相傷害其實是個好辦法
在已然發展很久的業務中,我們怎么解決此問題呢?
const QUOTA_EXCEEDED_ERR_CODE = 22 function write (key, data) { try { localStorage.setItem(key, data); } catch (e) { if (e.code === QUOTA_EXCEEDED_ERR_CODE) { localStorage.clear(); localStorage.setItem(key, data); } } }
上面這個方法還是有點問題,因為它把自己業務要用的東西也給刪了,所以自己的業務最好統一在 key 上加一個前綴,清空 localStorage 時只刪別人的。
有的同學可能會擔心,這樣會不會對其它業務造成傷害?或者產生一些難以發現的 bug。其實這種擔心很大程度上是因為忽略了實際的使用場景。用戶用同一個設備打開同一個 app,在同一個時間只能訪問一個業務,因此不會存在某個業務正在使用過程中,localStorage 被其它業務清掉的場景,除非!除非有交叉的業務場景。
一、如何得到localStorage已使用容量
(function(){ if(!window.localStorage) { console.log('瀏覽器不支持localStorage'); } var size = 0; for(item in window.localStorage) { if(window.localStorage.hasOwnProperty(item)) { size += window.localStorage.getItem(item).length; } } console.log('當前localStorage已使用容量為' + (size / 1024).toFixed(2) + 'KB'); })()
二、如何獲取localStorage最大容量
通過上面的分析,其實思路基本是一樣的,都是通過字符長度來判斷。
(function() { if(!window.localStorage) { console.log('當前瀏覽器不支持localStorage!') } var test = '0123456789'; var add = function(num) { num += num; if(num.length == 10240) { test = num; return; } add(num); } add(test); var sum = test; var show = setInterval(function(){ sum += test; try { window.localStorage.removeItem('test'); window.localStorage.setItem('test', sum); console.log(sum.length / 1024 + 'KB'); } catch(e) { console.log(sum.length / 1024 + 'KB超出最大限制'); clearInterval(show); } }, 0.5) })()
注:上面代碼可能卡死瀏覽器
相關鏈接:
https://www.cnblogs.com/kidney/p/9058352.html
https://www.cnblogs.com/MonkeyKingK/p/5499831.html