HTML5 Web 客户端五种离线存储方式汇总
2015-04-16 00:18 RTdo 阅读(695) 评论(0) 收藏 举报
摘要 最近折腾HTML5游戏需要离线存储功能,便把目前可用的几种HTML5存储方式研究了下,基于HT for Web写了个综合的实例,分别利用了Cookie、WebStorage、IndexedDB以及FileSystem四种本地离线存储方式,对燃气监控系统的表计位置、朝向、开关以及表值等信息做了CURD的存取操作。 HTML5的存储还有一种Web SQL Database方式,虽然还有浏览器支持,是唯一的关系数据库结构的存储,但W3C以及停止对其的维护和发展,所以这里我们也不再对其进行介绍:Beware. This specification is no longer in active ...
最近折腾HTML5游戏需要离线存储功能,便把目前可用的几种HTML5存储方式研究了下,基于HT for Web写了个综合的实例,分别利用了Cookie、WebStorage、IndexedDB以及FileSystem四种本地离线存储方式,对燃气监控系统的表计位置、朝向、开关以及表值等信息做了CURD的存取操作。
HTML5的存储还有一种Web SQL Database方式,虽然还有浏览器支持,是唯一的关系数据库结构的存储,但W3C以及停止对其的维护和发展,所以这里我们也不再对其进行介绍:Beware. This specification is no longer in active maintenance and the Web Applications Working Group does not intend to maintain it further.
整个示例主要就是将HT for Web的DataModel数据模型信息进行序列化和反序列化,这个过程很简单通过dataModel.serialize()将模型序列化成JSON字符串,通过dataModel.deserialize(jsonString)将JSON字符串内存反序列化出模型信息,而存储主要就是主要就是针对JSON字符串进行操作。
先介绍最简单的存储方式LocalStorage,代码如下,几乎不用介绍就是Key-Value的简单键值对存储结构,Web Storage除了localStorage的持久性存储外,还有针对本次回话的sessionStorage方式,一般情况下localStorage较为常用,更多可参考 http://www.w3.org/TR/webstorage/
1234567891011121314151617181920212223functionsave(dataModel){varvalue = dataModel.serialize();window.localStorage['DataModel'] = value;window.localStorage['DataCount'] = dataModel.size();console.log(dataModel.size() +' datas are saved');returnvalue;}functionrestore(dataModel){varvalue = window.localStorage['DataModel'];if(value){dataModel.deserialize(value);console.log(window.localStorage['DataCount'] +' datas are restored');returnvalue;}return'';}functionclear(){if(window.localStorage['DataModel']){console.log(window.localStorage['DataCount'] +' datas are cleared');deletewindow.localStorage['DataModel'];deletewindow.localStorage['DataCount'];}}最古老的存储方式为Cookie,本例中我只能保存一个图元的信息,这种存储方式存储内容很有限,只适合做简单信息存储,存取接口设计得极其反人类,为了介绍HTML5存储方案的完整性我顺便把他给列上:
12345678910111213141516171819202122232425262728293031323334353637functiongetCookieValue(name) {if(document.cookie.length > 0) {varstart = document.cookie.indexOf(name +"=");if(start !== -1) {start = start + name.length + 1;varend = document.cookie.indexOf(";", start);if(end === -1){end = document.cookie.length;}returnunescape(document.cookie.substring(start, end));}}return'';}functionsave(dataModel) {varvalue = dataModel.serialize();document.cookie ='DataModel='+ escape(value);document.cookie ='DataCount='+ dataModel.size();console.log(dataModel.size() +' datas are saved');returnvalue;}functionrestore(dataModel){varvalue = getCookieValue('DataModel');if(value){dataModel.deserialize(value);console.log(getCookieValue('DataCount') +' datas are restored');returnvalue;}return'';}functionclear() {if(getCookieValue('DataModel')){console.log(getCookieValue('DataCount') +' datas are cleared');document.cookie ="DataModel=; expires=Thu, 01 Jan 1970 00:00:00 UTC";document.cookie ="DataCount=; expires=Thu, 01 Jan 1970 00:00:00 UTC";}}如今比较实用强大的存储方式为Indexed Database API,IndexedDB可以存储结构对象,可构建key和index的索引方式查找,目前各浏览器的已经逐渐支持IndexedDB的存储方式,其使用代码如下,需注意IndexedDB的很多操作接口类似NodeJS的异步回调方式,特别是查询时连cursor的continue都是异步再次回调onsuccess函数的操作方式,因此和NodeJS一样使用上不如同步的代码容易。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182request = indexedDB.open("DataModel");request.onupgradeneeded =function() {db = request.result;varstore = db.createObjectStore("meters", {keyPath:"id"});store.createIndex("by_tag","tag", {unique:true});store.createIndex("by_name","name");};request.onsuccess =function() {db = request.result;};functionsave(dataModel){vartx = db.transaction("meters","readwrite");varstore = tx.objectStore("meters");dataModel.each(function(data){store.put({id: data.getId(),tag: data.getTag(),name: data.getName(),meterValue: data.a('meter.value'),meterAngle: data.a('meter.angle'),p3: data.p3(),r3: data.r3(),s3: data.s3()});});tx.oncomplete =function() {console.log(dataModel.size() +' datas are saved');};returndataModel.serialize();}functionrestore(dataModel){vartx = db.transaction("meters","readonly");varstore = tx.objectStore("meters");varreq = store.openCursor();varnodes = [];req.onsuccess =function() {varres = req.result;if(res){varvalue = res.value;varnode = createNode();node.setId(value.id);node.setTag(value.tag);node.setName(value.name);node.a({'meter.value': value.meterValue,'meter.angle': value.meterAngle});node.p3(value.p3);node.r3(value.r3);node.s3(value.s3);nodes.push(node);res.continue();}else{if(nodes.length){dataModel.clear();nodes.forEach(function(node){dataModel.add(node);});console.log(dataModel.size() +' datas are restored');}}};return'';}functionclear(){vartx = db.transaction("meters","readwrite");varstore = tx.objectStore("meters");varreq = store.openCursor();varcount = 0;req.onsuccess =function(event) {varres = event.target.result;if(res){store.delete(res.value.id);res.continue();count++;}else{console.log(count +' datas are cleared');}};}最后是FileSystem API相当于操作本地文件的存储方式,目前支持浏览器不多,其接口标准也在发展制定变化中,例如在我写这个代码时大部分文献使用的webkitStorageInfo已被navigator.webkitPersistentStorage和navigator.webkitTemporaryStorage替代,存储的文件可通过filesystem:http://www.hightopo.com/persistent/meters.txt’的URL方式在chrome浏览器中查找到,甚至可通过filesystem:http://www.hightopo.com/persistent/类似目录的访问,因此也可以动态生成图片到本地文件,然后通过filesystem:http:***的URL方式直接赋值给img的html元素的src访问,因此本地存储打开了一扇新的门,相信以后会冒出更多稀奇古怪的奇葩应用。
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647navigator.webkitPersistentStorage.queryUsageAndQuota(function(usage, quota) {console.log('PERSISTENT: '+ usage +'/'+ quota +' - '+ usage / quota +'%');});navigator.webkitPersistentStorage.requestQuota(2 * 1024 * 1024,function(grantedBytes) {window.webkitRequestFileSystem(window.PERSISTENT, grantedBytes,function(fs) {window.fs = fs;});});functionsave(dataModel) {varvalue = dataModel.serialize();fs.root.getFile('meters.txt', {create:true},function(fileEntry) {console.log(fileEntry.toURL());fileEntry.createWriter(function(fileWriter) {fileWriter.onwriteend =function() {console.log(dataModel.size() +' datas are saved');};varblob =newBlob([value], {type:'text/plain'});fileWriter.write(blob);});});returnvalue;}functionrestore(dataModel) {fs.root.getFile('meters.txt', {},function(fileEntry) {fileEntry.file(function(file) {varreader =newFileReader();reader.onloadend =function(e) {dataModel.clear();dataModel.deserialize(reader.result);console.log(dataModel.size() +' datas are restored');};reader.readAsText(file);});});return'';}functionclear() {fs.root.getFile('meters.txt', {create:false},function(fileEntry) {fileEntry.remove(function() {console.log(fileEntry.toURL() +' is removed');});});}Browser-Side的存储方式还在快速的发展中,其实除了以上几种外还有Application Cache,相信将来还会有新秀出现,虽然“云”是大趋势,但客户端并非要走极端的“瘦”方案,这么多年冒出了这么多客户端存储方式,说明让客户端更强大的市场需求是强烈的,当然目前动荡阶段苦逼的是客户端程序员,除了要适配Mouse和Touch,还要适配各种屏,如今还得考虑适配各种存储,希望本文能在大家选型客户端存储方案时有点帮助,最后上段基于HT for Web操作HTML5存储示例的视频效果:http://v.youku.com/v_show/id_XODUzODU2MTY0.html


浙公网安备 33010602011771号