HTML5 Web 客户端五种离线存储方式汇总

最近折腾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.

Screen Shot 2014-12-22 at 1.39.12 AM

整个示例主要就是将HT for WebDataModel数据模型信息进行序列化和反序列化,这个过程很简单通过dataModel.serialize()将模型序列化成JSON字符串,通过dataModel.deserialize(jsonString)将JSON字符串内存反序列化出模型信息,而存储主要就是主要就是针对JSON字符串进行操作。

先介绍最简单的存储方式LocalStorage,代码如下,几乎不用介绍就是Key-Value的简单键值对存储结构,Web Storage除了localStorage的持久性存储外,还有针对本次回话的sessionStorage方式,一般情况下localStorage较为常用,更多可参考 http://www.w3.org/TR/webstorage/

1function save(dataModel){ 2    var value = dataModel.serialize(); 3    window.localStorage['DataModel'] = value; 4    window.localStorage['DataCount'] = dataModel.size(); 5    console.log(dataModel.size() + ' datas are saved'); 6    return value; 7} 8function restore(dataModel){   9    var value = window.localStorage['DataModel']; 10    if(value){ 11        dataModel.deserialize(value); 12        console.log(window.localStorage['DataCount'] + ' datas are restored'); 13        return value; 14    }     15    return ''; 16} 17function clear(){ 18    if(window.localStorage['DataModel']){ 19        console.log(window.localStorage['DataCount'] + ' datas are cleared'); 20        delete window.localStorage['DataModel']; 21        delete window.localStorage['DataCount'];          22    }    23}

最古老的存储方式为Cookie,本例中我只能保存一个图元的信息,这种存储方式存储内容很有限,只适合做简单信息存储,存取接口设计得极其反人类,为了介绍HTML5存储方案的完整性我顺便把他给列上:

1function getCookieValue(name) { 2    if (document.cookie.length > 0) { 3        var start = document.cookie.indexOf(name + "="); 4        if (start !== -1) { 5            start = start + name.length + 1; 6            var end = document.cookie.indexOf(";", start); 7            if (end === -1){ 8                end = document.cookie.length; 9            } 10            return unescape(document.cookie.substring(start, end)); 11        } 12    } 13    return ''; 14} 15function save(dataModel) { 16    var value = dataModel.serialize(); 17    document.cookie = 'DataModel=' + escape(value); 18    document.cookie = 'DataCount=' + dataModel.size();     19    console.log(dataModel.size() + ' datas are saved'); 20    return value; 21} 22function restore(dataModel){   23    var value = getCookieValue('DataModel'); 24    if(value){ 25        dataModel.deserialize(value); 26        console.log(getCookieValue('DataCount') + ' datas are restored'); 27        return value; 28    }     29    return ''; 30} 31function clear() { 32    if(getCookieValue('DataModel')){ 33        console.log(getCookieValue('DataCount') + ' datas are cleared'); 34        document.cookie = "DataModel=; expires=Thu, 01 Jan 1970 00:00:00 UTC"; 35        document.cookie = "DataCount=; expires=Thu, 01 Jan 1970 00:00:00 UTC";    36    } 37}

如今比较实用强大的存储方式为Indexed Database API,IndexedDB可以存储结构对象,可构建key和index的索引方式查找,目前各浏览器的已经逐渐支持IndexedDB的存储方式,其使用代码如下,需注意IndexedDB的很多操作接口类似NodeJS的异步回调方式,特别是查询时连cursor的continue都是异步再次回调onsuccess函数的操作方式,因此和NodeJS一样使用上不如同步的代码容易。

1request = indexedDB.open("DataModel"); 2request.onupgradeneeded = function() {   3    db = request.result; 4    var store = db.createObjectStore("meters", {keyPath: "id"}); 5    store.createIndex("by_tag", "tag", {unique: true}); 6    store.createIndex("by_name", "name");   7}; 8request.onsuccess = function() { 9    db = request.result; 10}; 11 12function save(dataModel){ 13    var tx = db.transaction("meters", "readwrite"); 14    var store = tx.objectStore("meters"); 15    dataModel.each(function(data){ 16        store.put({ 17            id: data.getId(), 18            tag: data.getTag(), 19            name: data.getName(), 20            meterValue: data.a('meter.value'), 21            meterAngle: data.a('meter.angle'), 22            p3: data.p3(), 23            r3: data.r3(), 24            s3: data.s3() 25        });     26    });    27    tx.oncomplete = function() { 28        console.log(dataModel.size() + ' datas are saved'); 29    };     30    return dataModel.serialize(); 31} 32function restore(dataModel){      33    var tx = db.transaction("meters", "readonly"); 34    var store = tx.objectStore("meters"); 35    var req = store.openCursor();   36    var nodes = []; 37    req.onsuccess = function() {         38        var res = req.result; 39        if(res){ 40            var value = res.value; 41            var node = createNode(); 42            node.setId(value.id); 43            node.setTag(value.tag); 44            node.setName(value.name);                         45            node.a({ 46                'meter.value': value.meterValue, 47                'meter.angle': value.meterAngle 48            }); 49            node.p3(value.p3);                     50            node.r3(value.r3); 51            node.s3(value.s3); 52            nodes.push(node);              53            res.continue(); 54        }else{ 55            if(nodes.length){ 56                dataModel.clear(); 57                nodes.forEach(function(node){ 58                    dataModel.add(node);                          59                }); 60                console.log(dataModel.size() + ' datas are restored'); 61            }              62        }        63    };     64    return ''; 65} 66function clear(){ 67    var tx = db.transaction("meters", "readwrite"); 68    var store = tx.objectStore("meters"); 69    var req = store.openCursor(); 70    var count = 0; 71    req.onsuccess = function(event) {         72        var res = event.target.result; 73        if(res){ 74            store.delete(res.value.id); 75            res.continue(); 76            count++; 77        }else{ 78            console.log(count + ' datas are cleared'); 79        }          80    }; 81 82}

最后是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访问,因此本地存储打开了一扇新的门,相信以后会冒出更多稀奇古怪的奇葩应用。

1navigator.webkitPersistentStorage.queryUsageAndQuota(function (usage, quota) { 2        console.log('PERSISTENT: ' + usage + '/' + quota + ' - ' + usage / quota + '%'); 3    } 4); 5navigator.webkitPersistentStorage.requestQuota(2 * 1024 * 1024, 6    function (grantedBytes) { 7        window.webkitRequestFileSystem(window.PERSISTENT, grantedBytes, 8            function (fs) { 9                window.fs = fs; 10            }); 11    } 12); 13function save(dataModel) { 14    var value = dataModel.serialize(); 15    fs.root.getFile('meters.txt', {create: true}, function (fileEntry) { 16        console.log(fileEntry.toURL()); 17        fileEntry.createWriter(function (fileWriter) { 18            fileWriter.onwriteend = function () { 19                console.log(dataModel.size() + ' datas are saved'); 20            }; 21            var blob = new Blob([value], {type: 'text/plain'}); 22            fileWriter.write(blob); 23        }); 24    }); 25    return value; 26} 27function restore(dataModel) { 28    fs.root.getFile('meters.txt', {}, function (fileEntry) { 29        fileEntry.file(function (file) { 30            var reader = new FileReader(); 31            reader.onloadend = function (e) { 32                dataModel.clear(); 33                dataModel.deserialize(reader.result); 34                console.log(dataModel.size() + ' datas are restored'); 35            }; 36            reader.readAsText(file); 37        }); 38    }); 39    return ''; 40} 41function clear() { 42    fs.root.getFile('meters.txt', {create: false}, function(fileEntry) { 43        fileEntry.remove(function() { 44            console.log(fileEntry.toURL() + ' is removed'); 45        }); 46    });     47}

Screen Shot 2014-12-22 at 12.53.48 AM

Browser-Side的存储方式还在快速的发展中,其实除了以上几种外还有Application Cache,相信将来还会有新秀出现,虽然“云”是大趋势,但客户端并非要走极端的“瘦”方案,这么多年冒出了这么多客户端存储方式,说明让客户端更强大的市场需求是强烈的,当然目前动荡阶段苦逼的是客户端程序员,除了要适配Mouse和Touch,还要适配各种屏,如今还得考虑适配各种存储,希望本文能在大家选型客户端存储方案时有点帮助,最后上段基于HT for Web操作HTML5存储示例的视频效果:http://v.youku.com/v_show/id_XODUzODU2MTY0.html

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

HTML5 Web 客户端五种离线存储方式汇总 - HelloWorld