今天咱們來說一講 Web 存儲有幾種機制,並弄清楚什麼是臨時存儲,什麼是持久存儲。git
你可能不知道的是:咱們日常口中所說的持久存儲 localStorage 不少時候實際上是系統級別的「臨時存儲」。github
Indexed DB 的操做是異步的,不會阻塞主線程的執行,能夠在 window、web workers、service workers 環境中使用。web
IndexedDB 是基於文件存儲的,API 較爲複雜,包含 v1 v2 的差別,建議經過類庫來使用,好比:Dexie.js。chrome
Cache Storage API 爲緩存的 Request/Response 對象提供存儲機制,常在 ServiceWorker 中應用。json
異步,不會阻塞主線程的執行,能夠在 window、web workers、service workers 環境中使用。api
同步,會阻塞主線程的執行。瀏覽器
通常用於儲存臨時性的少許的數據。緩存
SessionStorage 是標籤級別的,跟隨者標籤的生命週期,而且會隨着標籤的銷燬而清空數據。session
沒法在 web workers、service workers 環境中使用。異步
它只能儲存字符串,大小限制大約爲 5MB。
同步,會阻塞主線程的執行。
沒法在 web workers、service workers 環境中使用。
它只能儲存字符串,大小限制大約爲 5MB。
Cookies 有它的用途,但不適用於儲存數據。
Cookie 會在每次 HTTP 請求的時候攜帶在請求頭中,大致積的 Cookies 會顯著增長 HTTP 請求的負擔。
Cookies 讀寫是同步的,只能儲存字符串,而且沒法在 web workers 環境中使用。
File System API 和 FileWriter API 提供讀取或寫入文件到沙箱中(Sandboxed file system)。
它是異步的,不推薦使用,由於 File System API 只能在 Chromium 內核中使用。
File System Access API 設計用於便捷得讀取和編輯本地文件。
但在讀取或寫入本地文件的時候,須要得到用戶受權,而且受權狀態沒法持久化記錄。
Application Cache 已被棄用,不建議使用。
建議遷移至 service workers 或 Cache API。
現代瀏覽器大多數已經不會再提示用戶以受權更多的儲存空間了。
在大多數瀏覽器中,能夠經過 StorageManager API 檢測儲存空間總量與正在使用的量
if (navigator.storage && navigator.storage.estimate) { const quota = await navigator.storage.estimate(); // quota.usage -> Number of bytes used. // quota.quota -> Maximum number of bytes available. const percentageUsed = (quota.usage / quota.quota) * 100; console.log(`You've used ${percentageUsed}% of the available storage.`); const remaining = quota.quota - quota.usage; console.log(`You can write up to ${remaining} more bytes.`); }
// quota data { "quota": 299977904946, "usage": 27154039, "usageDetails": { "caches": 26813093, "indexedDB": 305864, "serviceWorkerRegistrations": 35082 } }
注意:
indexedDB 超限將會執行 onabort 回調,並拋出一個 DOMException 錯誤,須要處理它的 QuotaExceededError 異常。
const transaction = idb.transaction(['entries'], 'readwrite'); transaction.onabort = function(event) { const error = event.target.error; // DOMException if (error.name == 'QuotaExceededError') { // Fallback code goes here } };
拋出一個 Promise Rejection,QuotaExceededError 錯誤對象,須要處理它的 QuotaExceededError 異常。
try { const cache = await caches.open('my-cache'); await cache.add(new Request('/sample1.jpg')); } catch (err) { if (error.name === 'QuotaExceededError') { // Fallback code goes here } }
Web Storage 分爲兩種儲存模式,分別是:臨時存儲 Best Effort 和持久存儲 Persistent。
默認狀況下網站數據(包括 IndexedDB, Cache API, LocalStorage 等)都儲存在臨時存儲 Best Effort 中,會在存儲空間不足的時候被瀏覽器清除掉。
各個瀏覽器回收存儲空間的差別:
申請持久存儲 Persistent Storage:
// Request persistent storage for site if (navigator.storage && navigator.storage.persist) { const isPersisted = await navigator.storage.persist(); console.log(`Persisted storage granted: ${isPersisted}`); }
查看持久存儲 Persistent Storage 受權狀態:
// Check if site's storage has been marked as persistent if (navigator.storage && navigator.storage.persist) { const isPersisted = await navigator.storage.persisted(); console.log(`Persisted storage granted: ${isPersisted}`); }
各個瀏覽器申請持久存儲 Persistent Storage 的差別:
在 Chrome 55 之後,申請持久存儲只須要知足如下任一條件,便可自動得到持久存儲權限,無需用戶確認:
最後測試並驗證:
await navigator.storage.persist()
,返回 true
await navigator.storage.persist()
,返回 false