当前位置: 首页 > 科技观察

前端存储除了localStorage还有什么?

时间:2023-03-16 01:53:38 科技观察

前言前端的数据存储方式,除了Cookies、localStorage、sessionStorage,你用过其他存储方式吗?事实上,除了上面提到的三种存储方式,目前主流的浏览器还支持WebSQL和IndexedDB。目前市场上主流的浏览器包括Chrome、Safari、Firefox、Opera、UC浏览器和InternetExplorer等。其中,截至2020年5月,Chrome的市场份额为“63.93%”,远超第二名Safari(“18.19%”)。这里我们以市场占有率最大的Chrome浏览器为例,了解一下它支持的所有存储方案:(打开Chrome开发者工具,切换到应用栏目)介绍一些比较流行的开源前端——端存储解决方案之前,阿宝哥先分享了一些存储相关的有趣好玩的开源库。一、有趣好玩的开源库1.1Sharedb?基于OperationalTransformation(OT)的实时数据库后端。https://github.com/share/sharedb?ShareDB是一个基于JSON文档操作转换(OT)的实时数据库后端。它是DerbyJSWeb应用程序框架的实时后端。《示例1:实时数据同步》《示例2:显示实时查询的排行榜应用程序》1.2ImmortalDB?Arelentlesskey-valuestoreforthebrowser。https://github.com/gruns/ImmortalDB?ImmortalDB是在浏览器中存储持久键值获取数据的最佳方式。保存到ImmortalDB的数据冗余存储在Cookies、IndexedDB和localStorage中,如果其中的任何数据被删除或损坏,它们将不断自我修复。例如,清除cookie是一种常见的用户操作,即使对于非技术用户也是如此。在存储压力下,浏览器会在没有警告的情况下随意丢弃IndexedDB、localStorage或sessionStorage。"示例"import{ImmortalDB}from'immortal-db'awaitImmortalDB.set('name','semlinker');//SetawaitImmortalDB.get('name',default='lolo');//GetawaitImmortalDB.remove('name');//Remove1.3web-storage-cache扩展了localStorage和sessionStorage,增加了timeout和serialization方法。https://github.com/wuchangming/web-storage-cacheWebStorageCache扩展了HTML5localStorage和sessionStorage,“添加超时和序列化方法”。直接存储JSON对象即可,超时设置也很简单。优化:WebStorageCache自动清除访问的过期数据,避免过期数据堆积。另外还提??供了清除所有过期数据的方法:wsCache.deleteAllExpires();"Example"varwsCache=newWebStorageCache();//缓存字符串'wqteam'到'username',超时100秒wsCache.set('username','wqteam',{exp:100});//超时deadline,availableDatetypevarnextYear=newDate();nextYear.setFullYear(nextYear.getFullYear()+1);wsCache.set('username','wqteam',{exp:nextYear});//获取'的值username'inthecachewsCache.get('username');//缓存简单的js对象,默认序列化方式为JSON.stringify。//可以在初始化wsCache的时候配置serializer.serializewsCache.set('user',{name:'Wu',organization:'wqteam'});1.4lz-string基于LZ的JavaScript压缩算法。https://github.com/pieroxy/lz-string/lz-string旨在满足在localStorage中存储大量数据的需求,尤其是在移动设备上。localStorage通常限制在5MB~10MB,可以压缩数据以存储更多数据。"例子"varstring="Hello,mynameissemlinker";console.log("Sizeofsampleis:"+string.length);varcompressed=LZString.compress(string);console.log("Sizeofcompressedsampleis:"+compressed.length);string=LZString.decompress(压缩);console.log("Sampleis:"+string);下图是使用官方在线样例进行字符串压缩测试的结果:(图片来源:https://pieroxy.net/blog/pages/lz-string/demo.html)接下来介绍一些主流的数据库。2.主流数据库2.1localForage离线存储,改进。使用简单但功能强大的API包装IndexedDB、WebSQL或localStorage。https://github.com/localForage/localForagelocalForage是一个快速简单的JavaScript存储库。它通过使用类似于localStorage的简单API使用异步存储(IndexedDB或WebSQL)来改善Web应用程序的离线体验。对于不支持IndexedDB或WebSQL的浏览器,localForage将使用localStorage进行数据存储。此外,localForage还支持存储所有可以序列化为JSON的原生JS对象以及ArrayBuffers、Blob和TypedArrays。LocalForage主要支持平台:IE10(IE8+使用localStorage)Opera15(Opera10.5+使用localStorage)Firefox18Safari3.1(包括MobileSafari)Chrome23、ChromeforAndroid32Phonegap/ApacheCordova1.2.02.2PouchDB-PouchDB是袖珍型数据库。https://github.com/pouchdb/pouchdbPouchDB是一个浏览器内数据库,允许应用程序将数据保存在本地,以便用户即使在离线时也可以享受应用程序的所有功能。此外,数据在客户端之间同步,因此用户无论身在何处都可以保持最新状态。PouchDB也在Node.js中运行,可用作“CouchDB”兼容服务器的直接接口。API在每个环境中都以相同的方式工作,因此您可以减少担心浏览器差异的时间,而将更多时间用于编写干净、一致的代码。PouchDB支持所有现代浏览器:Firefox29+(包括FirefoxOS和FirefoxforAndroid)Chrome30+Safari5+InternetExplorer10+Opera21+Android4.0+iOS7.1+WindowsPhone8+PouchDB在幕后使用IndexedDB,如果当前如果环境不支持IndexedDB,它将回退到WebSQL。2.3Rxdb用于JavaScript应用程序的实时数据库。https://github.com/pubkey/rxdbRxDB(ReactiveDatabase的缩写)是一个NoSQL数据库,用于JavaScript应用程序,例如网站、混合应用程序、ElectronApps、ProgressiveWebApps和Node.js。响应式意味着你不仅可以查询当前状态,还可以订阅所有状态变化,比如查询的结果或者文档的单个字段。这对于基于实时UI的应用程序非常有用,因为它易于开发并且具有很大的性能优势。为了在客户端和服务器之间复制数据,RxDB提供了用于与任何CouchDB兼容端点以及自定义GraphQL端点进行实时复制的模块。RxDB支持以下特性:Mango-Query:支持mqueryAPI从集合中获取数据,支持链式mongoDB查询风格。Replication:由于RxDB依赖于PouchDB,所以很容易实现终端设备和服务器之间的数据同步。反应式:RxDB可以轻松同步DOM的状态。MultiWindow/Tab:当两个RxDB实例使用同一个存储引擎时,它们的状态和操作流程将被广播。这意味着对于两个浏览器窗口,窗口#1中的数据更改也会自动影响窗口#2中的数据状态。Schema:Schemas由jsonschema定义,用于描述数据格式。加密:通过将模式字段设置为加密,该字段的值将以加密方式存储,没有密码无法读取。2.4NeDBJavaScript数据库,用于Node.js、nw.js、electron和浏览器。https://github.com/louischatriot/nedbNeDB是一个可以运行在Node.js、nw.js、Electron和浏览器环境上的JavaScript数据库。它使用纯JavaScript实现,不依赖于其他库。提供的API是MongoDBAPI的一个子集。重要的是它非常快:插入:10,680ops/s查找:43,290ops/s更新:8,000ops/s。删除:11,750次操作/秒。ops(operationpersecond)表示每秒的操作数。2.5Dexie.jsIndexedDB的简约包装器。https://github.com/dfahlander/Dexie.jsDexie.js是IndexedDB的包装库,它提供了设计良好的API、强大的错误处理和强大的可扩展性,此外,它还可以跟踪数据变化并支持KeyRange(搜索不区分大小写,可以设置匹配方式和OR运算)。Dexie.js主要是为了解决原生IndexedDBAPI中的三个主要问题:异常错误处理。查询功能弱。代码复杂度。为了方便开发者接入Dexie.js,Dexie.js官网提供了丰富的示例:React+DexieReact+Redux+DexieDexiewithTypescriptAngular+DexieDexiewithElectronFullTextSearch以上仅列举一些示例,了解更多示例,请访问:Dexie.js-Samples(https://dexie.org/docs/Samples)。最后简单介绍一下各种网络存储方案。3、各种网页存储方案介绍3.1CookieHTTPCookie(也称为WebCookie或BrowserCookie)是服务器发送给用户浏览器并存储在本地的一小段数据。下次将由浏览器发送到同一服务器。它在请求时被携带并发送到服务器。通常用来告诉服务器两个请求是否来自同一个浏览器,比如保持用户登录状态。Cookies主要用在以下三个方面:会话状态管理(比如用户登录状态、购物车、游戏分数或其他需要记录的信息);个性化设置(如用??户自定义设置、主题等);浏览器行为跟踪(如跟踪和分析用户行为等)。cookies的特点:cookies的大小是有限的,一般为4KB;同一个域名下存储的cookie数量有限,不同浏览器数量不同,一般为20个;cookies支持设置过期时间,当过期时会自动销毁;每次发起同域下的HTTP请求,都会携带当前域名下的cookie;可以将其设置为HttpOnly以防止cookie被客户端的JavaScript访问。"示例1:简单用法"document.cookie="name=semlinker";document.cookie="favorite_food=tripe";alert(document.cookie);//显示:name=semlinker;favorite_food=tripe"示例2:获取一个名为test2"document.cookie="test1=Hello";document.cookie="test2=World";varmyCookie=document.cookie.replace(/(?:(?:^|.*;\s*)test2\s*\=\s*([^;]*).*$)|^.*$/,"$1");alert(myCookie);3.2localStorage是一种持久化存储方式,也就是说Data从不除非手动清除,否则会过期。它以键值对的形式存储数据,根据域名将数据保存在相应的数据库文件中。与cookies相比,它可以保存更大的数据。localStorage的特点:大小限制在5MB~10MB;数据在同源的所有选项卡和窗口之间共享;数据只保存在客户端,不与服务器通信;数据持久存在,不会过期,重启浏览器后依然存在;对数据的操作是同步的。"Example"//通过setItem()添加一个数据项localStorage.setItem('myName','Semlinker');//通过getItem()获取一个数据项letme=localStorage.getItem('myName');//移除adataitemthroughremoveItem()localStorage.removeItem('myName');//移除所有数据项localStorage.clear();3.3sessionStorage类似于服务器端的session,sessionStorage是session级的缓存,close浏览器打开时数据会被清除。需要注意的是,sessionStorage的作用域是窗口级别的,也就是说不同窗口之间保存的sessionStorage数据是不能共享的。sessionStorage的特点:sessionStorage的数据只存在于当前浏览器的标签页中;页面刷新后数据仍然存在,但关闭浏览器选项卡后数据会被清除;与localStorage有统一的API接口;操作是同步的。"Example"//通过setItem()添加一个数据项sessionStorage.setItem('myName','Semlinker');//通过getItem()获取一个数据项letme=sessionStorage.getItem('myName');//移除adataitemthroughremoveItem()sessionStorage.removeItem('myName');//移除所有数据项sessionStorage.clear();3.4WebSQLWebSQL数据库API其实并不是HTML5规范的一部分,而是一个单独的规范,引入了一组API来使用SQL来操作客户端数据库。需要注意的是,HTML5已经放弃了WebSQL数据库。WebSQL数据库规范中定义的三个核心方法:openDatabase:该方法使用现有数据库或新数据库创建数据库对象;transaction:该方法允许我们根据情况控制事务的提交或回滚;executeSql:该方法用于执行真正的SQL语句。WebSQL的特点(相对于Cookie、localStorage、sessionStorage):WebSQL可以方便对象存储;WebSQL支持事务,可以方便的进行数据查询和数据处理操作。"例子"vardb=openDatabase('mydb','1.0','TestDB',2*1024*1024);db.transaction(function(tx){//执行查询操作tx.executeSql('CREATETABLEIFNOTEXISTSLOGS(idunique,log)');//执行插入操作tx.executeSql('INSERTINTOLOGS(id,log)VALUES(1,"foobar")');tx.executeSql('INSERTINTOLOGS(id,log)VALUES(2,"logmsg")');});3.5IndexedDBIndexedDB是用于客户端存储大量结构化数据(包括文件和二进制大对象)的低级API。API使用索引来实现此数据的高性能搜索。虽然WebStorage对于存储少量数据很有用,但对于存储大量结构化数据就没那么有用了。IndexedDB提供了一种解决方案。IndexedDB的特点:存储空间大:存储空间可达数百兆甚至更多;支持二进制存储:不仅可以存储字符串,还可以存储二进制数据;可以在域名下访问,不能跨域名访问;支持事务类型:IndexedDB执行的操作会根据事务进行分组,在一个事务中,要么全部操作成功,要么全部操作失败;键值对存储:IndexedDB对象存储,内部用于存储数据。所有类型的数据都可以直接存储,包括JavaScript对象。在对象仓库中,数据以“键值对”的形式存储。每条数据记录都有对应的主键。主键是唯一的,不能重复,否则会报错。数据操作是异步的:使用IndexedDB执行的操作是异步执行的,以免阻塞应用程序。"例子"vardbName="my_db";varrequest=indexedDB.open(dbName,2);request.onerror=function(event){//错误处理};request.onupgradeneeded=function(event){vardb=event.target.result;//建立一个对象仓库来存储我们客户的相关信息,我们选择ssn作为键路径(keypath)//因为ssn可以保证唯一varobjectStore=db.createObjectStore("customers",{keyPath:"ssn"});//建立索引,按姓名搜索客户。名字可能会重复,所以我们不能使用唯一索引会重复,所以我们使用uniqueIndexobjectStore.createIndex("email","email",{unique:true});//使用事务的oncomplete事件保证在插入数据objectStore之前已经创建了对象存储。transaction.oncomplete=function(event){//将数据保存到新创建的对象存储varcustomerObjectStore=db.transaction("customers","re??adwrite").objectStore("customers");customerData.forEach(function(customer){customerObjectStore.add(客户);});};};空间有限。这里只介绍一些开源库。其实还有一些其他成熟的开源库,比如lowdb(LocalJSONDatabase)、Lovefield(RelationalDatabase)和LokiJS(NoSQLDatabase)等。