localStorage 存滿了怎么辦?


先來幾道面試題

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM