今天咱们来说一讲 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