前言今天我们就来聊一聊Web存储的几种机制,搞清楚什么是临时存储,什么是持久存储。你可能不知道的是,我们通常所说的持久化存储localStorage,在很多情况下其实是一种系统级的“临时存储”。TextIndexedDBIndexedDB的操作是异步的,不会阻塞主线程的执行。它可以在窗口、网络工作者和服务工作者环境中使用。IndexedDB是基于文件存储的,API比较复杂,包括v1和v2的区别。推荐通过类库来使用,比如:Dexie.js。CacheStorageAPICacheStorageAPI为缓存的Request/Response对象提供了一种存储机制,常用于ServiceWorker中。异步的,不会阻塞主线程的执行,可用于window、webworkers、serviceworkers环境。SessionStorage同步会阻塞主线程的执行。一般用来存放少量的临时数据。SessionStorage是标签级别的,跟随标签的生命周期,随着标签的销毁会清除数据。不能用于webworkers、serviceworkers环境。它只能存储字符串,大小限制在5MB左右。LocalStorage同步会阻塞主线程的执行。不能用于webworkers、serviceworkers环境。它只能存储字符串,大小限制在5MB左右。CookiesCookies有其用途,但不适合存储数据。每次HTTP请求都会在请求头中携带Cookie,大的Cookie会明显增加HTTP请求的负担。Cookies是同步读写的,只能存储字符串,不能在webworkers环境中使用。文件系统API文件系统API和FileWriterAPI提供读取或写入文件到沙箱(Sandboxedfilesystem)。它是异步的,不推荐使用,因为文件系统API仅在Chromium核心中可用。文件系统访问API文件系统访问API旨在轻松读取和编辑本地文件。但是在读写本地文件时,需要用户授权,授权状态不能持久化记录。应用程序缓存应用程序缓存已弃用,不推荐使用。建议迁移到ServiceWorker或CacheAPI。Storage可以使用多少磁盘空间?Chrome允许使用80%的硬盘空间,单个源(域名)可以使用60%的硬盘空间。可以通过StorageManagerAPI检测最大硬盘空间限制。其他基于Chromium的浏览器有不同的限制,可能允许使用更多的硬盘空间,查看更多PR#3896InternetExplorer10(IE10)及以上版本,最多可存储250MB,超过10MB时会提示用户。Firefox允许使用50%的空闲硬盘空间,一个级别的域名最多可以使用2GB的硬盘空间,最大硬盘空间限制可以通过StorageManagerAPI检测。Safari允许使用1GB。当达到1GB时,会提示用户(这个数据可能不准确,找不到官方的Safari文档)。大多数现代浏览器都不再提示用户授权更多存储。如何查看存储空间是否可用?在大多数浏览器中,可以通过StorageManagerAPI检测存储空间总量和使用量if(navigator.storage&&navigator.storage.estimate){//配额。usage->使用的字节数。//quota.quota->最大可用字节数。constpercentageUsed=(quota.usage/quota.quota)*100;console.log(`您已经使用了${percentageUsed}%的可用存储空间。`);constremaining=quota.quota-quota.usage;console.log(`您最多可以写入${remaining}个字节。`);}//配额数据{"quota":299977904946,"usage":27154039,"usageDetails":{"caches":26813093,"indexedDB":305864,"serviceWorkerRegistrations":35082}}注意:并不是所有的浏览器都实现了,所以在使用前需要判断兼容性需要捕获并处理超出配额限制的错误。IndexedDBoverrun处理indexedDBoverrun会执行onabort回调并抛出DOMException错误,需要处理其QuotaExceededError异常。consttransaction=idb.transaction(['entries'],'readwrite');transaction.onabort=function(event){consterror=event.target.error;//DOMExceptionif(error.name=='QuotaExceededError'){//回退代码在这里}};CacheAPIoverrun处理抛出PromiseRejection,QuotaExceededError错误对象,需要处理其QuotaExceededError异常。尝试{constcache=awaitcaches.open('my-cache');awaitcache.add(newRequest('/sample1.jpg'));}catch(err){if(error.name==='QuotaExceededError'){//Fallbackcodegoeshere}}浏览器什么时候回收存储空间?WebStorage分为两种存储模式:临时存储BestEffort和持久存储Persistent。默认情况下,网站数据(包括IndexedDB、CacheAPI、LocalStorage等)存储在临时存储BestEffort中,存储空间不足时会被浏览器清除。浏览器回收存储空间的区别:当浏览器的存储空间不足时,Chrome会优先将最近最少使用的数据一项一项地清除,直到不再超过限制为止。IE10+不会自动清除数据,但会阻止站点继续写入导入数据Firefox当磁盘空间满时,会先将最近最少使用的数据一一清除,直到不再超过限制Safari(iOS,iPadOS,MacOS)会自动清除7天以前的数据,但不会清除“已经添加到主屏幕”网站和“PWA”网站申请并查看持久化存储PersistentStorage申请持久化存储://请求持久化siteif的存储(navigator.storage&&navigator.storage.persist){constisPersisted=awaitnavigator.存储.persist();console.log(`Persistedstoragegranted:${isPersisted}`);}CheckPersistentStorageauthorizationstatus://检查站点的存储是否被标记为persistentif(navigator.storage&&navigator.storage.persist){constisPersisted=awaitnavigator.storage.persisted();console.log(`Persistedstoragegranted:${isPersisted}`);}不同浏览器申请持久化存储:Chrome55以后,申请持久化存储只需要满足以下任一条件即可自动获取持久化存储权限,无需用户确认:该站点已被收藏,且用户收藏数小于或等于5个“siteengagement”高的站点,通过此命令可以查看:chrome://site-engagement/站点已添加到主屏站点已启用推送通知功能在Firefox中会提示用户授权最后测试验证:openhttps://baidu.com,打开控制台,输入awaitnavigator.storage.persist(),返回true,打开https://wy.guahao.com,打开控制台,输入awaitnavigator.storage.persist(),returnfalse参考文献《Storage for the web》《Persistent storage》
