QuotaExceededError: The quota has been exceeded. localStorage緩存超出限制


今天在項目中遇到了一個問題,localStorage存儲超出限制。報錯信息如標題。這個是因為最近做了一波優化,把導航欄和一些用戶信息本地化存儲,都放在localStorage里,也不是每個用戶會出現這種問題。

其實同一個域名下可能存在幾十上百條業務線,每條業務線都可能因為各種理由往 localStorage 里塞東西,跨頁面傳數據啦、緩存啦、離線化啦、性能優化啦...,5M 看起來很多,其實很快就用完了。而開發時基本無感知,是因為大家都只訪問自己的業務,但用戶會訪問各種業務,時間一久,很容易就存滿了,凡是嚴重依賴 localStorage 的業務流程都存在風險。

Hybrid APP:一種容易想到的方案是,當 localStorage 存滿后降級到 sessionStorage 里。看上去沒啥問題,但實際業務中 app 內 h5 頁面跳轉常常采用新打開 webview 的方式,這么做的好處是關閉一個 webview 可以直接回到上一個頁面,而不用重新加載頁面,對於訂單填寫這類帶有狀態的頁面就很需要這么做。新打開 webview 等於新打開一個會話,而 sessionStorage 只能存在於同一個會話中,因此 sessionStorage 無法跨頁面共享。

那降級到 cookie 里呢?cookie 一共才 50 個,總大小不超過 4k,作為 backup 過於脆弱,而且還會影響請求的效率。如果后端對請求頭大小做了限制,還可能產生 413 錯誤,導致請求被攔截。

那降級到 url 上呢?很麻煩。比如有一個交互流程是這樣的:頁面 A => 頁面 B => 頁面 C,如果頁面 A 的數據要傳到頁面 C,就得通過頁面 B 做一層中轉。而且 url 長度也是有限制的。

單頁面應用在不影響業務的情況下,可以直接從localStorage里降到sessionStorage。

我們還可以求助客戶端同學,通過 js bridge 提供一個仿 localStorage 的東西,不過要考慮版本的問題,新版 app 里使用了客戶端提供的 store,怎么兼顧老版 app,而且還要考慮兼容瀏覽器、微信。所以這種方案也只能解決一部分問題,當然,如果 h5 的流量絕大多數都在 app 里,那么這種方案是可以解決一大部分問題的,不過客戶端提供的存儲可不見得比原生的存儲可靠,還是得加 backup。

我們還可以求助后端同學,多加幾個字段甚至多加幾個接口,不過這涉及到核心業務流程的改造,風險不小,而且不見得能完全解決問題,也無法永久的解決問題。

我們還可以來一招互相傷害大法,那就是把別人存的東西都刪掉。。。

還有一個很討厭的事情:safari 在隱私模式下不支持 localStorage 的存取(ios11 以下),這種情況比較罕見,但如果出了客訴,也是個大坑。

localStorage 歸根結底就兩個作用:持久化存儲與跨頁面傳數據。持久化存儲不會出問題,存不進去就存不進去唄,取不出來就去其它地方取,或者不取。問題就出在跨頁面傳數據上,上一個頁面因為 localStorage 存滿導致數據沒有寫入,下一個頁面讀取數據為空,從而導致錯誤。

理想的方案

假設我們回到起點,從零建設前端工程,我們怎么避免 localStorage 存滿的問題?

1、划分域名。各域名下的存儲空間由各業務組統一規划使用

2、跨頁面傳數據:考慮單頁應用、優先采用 url 傳數據

3、最后的兜底方案:清掉別人的存儲

 

目前的問題是它既不存,也不跳轉,稍改動一下,如下:

try {
  localStorage.setItem("nearbycorp",JSON.stringify(this.state));
  localStorage.setItem('nearbycorp_scrolltop', $('.list .am-list-view-scrollview')[0].scrollTop);
}catch (err){
  console.log(err)
}finally {
  location.hash = "/customer/detail/" + corp.id;
}

因為該頁面存的是跳轉到另外一個hash時存儲了當前頁面的篩選條件和滾動高度,結果就是不會滾動到剛剛的瀏覽區域。對用戶造成一定的影響。所以還是直接存儲到sessionStorage里比較好,不會影響用戶。

 

 

查詢localStorage限制的網址: http://dev-test.nemikor.com/web-storage/support-test/

try {
      sessionStorage.setItem("nearbycorp",JSON.stringify(this.state));
      sessionStorage.setItem('nearbycorp_scrolltop', $('.list .am-list-view-scrollview')[0].scrollTop);
    }catch (err){
      console.log(err)
    }finally {
      location.hash = "/customer/detail/" + corp.id;
    }

當然,這個問題應該從項目創建就考慮到,不必要存到localStorage的數據盡量不要存,避免后面出現這種問題。

 


免責聲明!

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



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