HTML5的五种客户端离线存储方案

简介: 最近折腾HTML5游戏需要离线存储功能,便把目前可用的几种HTML5存储方式研究了下,基于HT for Web写了个综合的实例,分别利用了Cookie、WebStorage、IndexedDB以及FileSystem四种本地离线存储方式,对燃气监控系统的表计位置、朝向、开关以及表值等信息做了CURD的存取操作。

最近折腾HTML5游戏需要离线存储功能,便把目前可用的几种HTML5存储方式研究了下,基于HT for Web写了个综合的实例,分别利用了Cookie、WebStorage、IndexedDB以及FileSystem四种本地离线存储方式,对燃气监控系统的表计位置、朝向、开关以及表值等信息做了CURD的存取操作。

http://www.hightopo.com/guide/guide/core/serialization/examples/example_exportimport.html

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/

function save(dataModel){
    var value = dataModel.serialize();
    window.localStorage['DataModel'] = value;
    window.localStorage['DataCount'] = dataModel.size();
    console.log(dataModel.size() + ' datas are saved');
    return value; } function restore(dataModel){ var value = window.localStorage['DataModel']; if(value){ dataModel.deserialize(value); console.log(window.localStorage['DataCount'] + ' datas are restored'); return value; } return ''; } function clear(){ if(window.localStorage['DataModel']){ console.log(window.localStorage['DataCount'] + ' datas are cleared'); delete window.localStorage['DataModel']; delete window.localStorage['DataCount']; } }

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

function getCookieValue(name) {
    if (document.cookie.length > 0) {
        var start = document.cookie.indexOf(name + "=");
        if (start !== -1) {
            start = start + name.length + 1;
            var end = document.cookie.indexOf(";", start); if (end === -1){ end = document.cookie.length; } return unescape(document.cookie.substring(start, end)); } } return ''; } function save(dataModel) { var value = dataModel.serialize(); document.cookie = 'DataModel=' + escape(value); document.cookie = 'DataCount=' + dataModel.size(); console.log(dataModel.size() + ' datas are saved'); return value; } function restore(dataModel){ var value = getCookieValue('DataModel'); if(value){ dataModel.deserialize(value); console.log(getCookieValue('DataCount') + ' datas are restored'); return value; } return ''; } function clear() { 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一样使用上不如同步的代码容易。

request = indexedDB.open("DataModel");
request.onupgradeneeded = function() {  
    db = request.result;
    var store = db.createObjectStore("meters", {keyPath: "id"});
    store.createIndex("by_tag", "tag", {unique: true});
    store.createIndex("by_name", "name"); }; request.onsuccess = function() { db = request.result; }; function save(dataModel){ var tx = db.transaction("meters", "readwrite"); var store = 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'); }; return dataModel.serialize(); } function restore(dataModel){ var tx = db.transaction("meters", "readonly"); var store = tx.objectStore("meters"); var req = store.openCursor(); var nodes = []; req.onsuccess = function() { var res = req.result; if(res){ var value = res.value; var node = 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 ''; } function clear(){ var tx = db.transaction("meters", "readwrite"); var store = tx.objectStore("meters"); var req = store.openCursor(); var count = 0; req.onsuccess = function(event) { var res = 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访问,因此本地存储打开了一扇新的门,相信以后会冒出更多稀奇古怪的奇葩应用。

navigator.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; }); } ); function save(dataModel) { var value = 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'); }; var blob = new Blob([value], {type: 'text/plain'}); fileWriter.write(blob); }); }); return value; } function restore(dataModel) { fs.root.getFile('meters.txt', {}, function (fileEntry) { fileEntry.file(function (file) { var reader = new FileReader(); reader.onloadend = function (e) { dataModel.clear(); dataModel.deserialize(reader.result); console.log(dataModel.size() + ' datas are restored'); }; reader.readAsText(file); }); }); return ''; } function clear() { fs.root.getFile('meters.txt', {create: false}, function(fileEntry) { fileEntry.remove(function() { console.log(fileEntry.toURL() + ' is removed'); }); }); }

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

http://www.hightopo.com/guide/guide/core/serialization/examples/example_exportimport.html

目录
相关文章
|
6月前
|
搜索推荐 API SEO
Angular 服务器端渲染的静态 HTML 变为客户端的动态应用的过程
Angular 服务器端渲染的静态 HTML 变为客户端的动态应用的过程
69 1
|
6月前
|
存储 Web App开发 移动开发
HTML5在客户端存储数据的新方法——localStorage
HTML5在客户端存储数据的新方法——localStorage
91 0
|
7月前
|
JavaScript UED
Angular 服务器端渲染场景里,服务器端和客户端渲染出的 HTML 源代码有可能不完全一致
Angular 服务器端渲染场景里,服务器端和客户端渲染出的 HTML 源代码有可能不完全一致
60 0
|
10月前
Echarts除了tooltip其它的标签暂时都不支持html情况下label标签加背景图片的美化方案
Echarts除了tooltip其它的标签暂时都不支持html情况下label标签加背景图片的美化方案
83 0
|
12月前
|
移动开发 前端开发 JavaScript
Spring MVC-09循序渐进之文件上传(基于Servlet3.0+Html5客户端上传文件)
Spring MVC-09循序渐进之文件上传(基于Servlet3.0+Html5客户端上传文件)
52 0
|
XML JavaScript 前端开发
AndroidQ(10.0) 手机锁屏炫酷充电动画————html方案
AndroidQ(10.0) 手机锁屏炫酷充电动画————html方案
103 1
|
移动开发 JavaScript 前端开发
【浏览器&exe桌面应用】用nw.js &Electron -HTML和JavaScript制作exe桌面程序-打造浏览器,查询机客户端,大屏展示客户端
【浏览器&exe桌面应用】用nw.js &Electron -HTML和JavaScript制作exe桌面程序-打造浏览器,查询机客户端,大屏展示客户端
135 0
|
存储 缓存 移动开发
前端开发面试题—HTML5应用程序缓存 (离线存储)
今天分享一下我遇到的前端面试题,什么是HTML5应用程序缓存 (离线存储) ?
204 0
前端开发面试题—HTML5应用程序缓存 (离线存储)
|
存储 移动开发 缓存
HTML5相关面试题:1.H5新特性;2. HTML5 新标签的浏览器兼容问题;3.H5 的离线存储;4.H5缓存和常规缓存有什么差别;5:H5缓存优势;6.Web Worker 和Web作用
●拖放(Drag and drop) API. ●语义化更好的内容标签( header、nav、footer、 aside、 article、 section )。 ●音频、 视频(audio、video) API。 ●画布( Canvas) API。 ●地理( Geolocation) API。 ●本地离线存储( localStorage),即长期存储数据,浏览器关闭后数据不丢失。 ●会话 存储( sessionStorage),即数据在浏览器关闭后自动删除。 ●表单控件包括calendar、date、 time、 email、 url、 search ●新的技术包括webworker、we
188 0
|
前端开发 JavaScript
分享一段小代码,处理原生html下移动端的适配方案
分享一段小代码,处理原生html下移动端的适配方案
163 0