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

Web SQL Database

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/

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

最古老的存储方式为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

如今比较实用强大的存储方式为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

最后是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');

});

});

}

Application Cache

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

HTML5数据库建模,HTML5的五种客户端离线存储方案相关推荐

  1. 深度点评五种常见WiFi搭建方案

    总结十年无线搭建经验,针对企业常见的五种办公室无线网络方案做个简要分析,各种方案有何优劣,又适用于那种类型的企业. 方案一:仅路由器或AP覆盖 简述:使用路由器或AP覆盖多个无线盲区,多个AP的部署实 ...

  2. 常见html5营销类型有哪些,五种常见的营销策略

    网络营销的成功往往在于策略.给大家介绍几个在策略中经常用的方式. 1.折扣营销 折扣营销策略简单说就是给产品打折,这是常用的促销方式,折扣营销,迎合了消费者少花钱的心理,所以,这一方式在销售上也是比较 ...

  3. 四种有能力取代Cookies的客户端Web存储方案

    目前在用户的网络浏览器中保存大量数据需要遵循几大现有标准,每一种标准都拥有自己的优势.短板.独特的W3C标准化状态以及浏览器支持级别.但无论如何,这些标准的实际表现都优于广泛存在的cookies机制. ...

  4. 【数据库Redis】Redis五种基本数据结构以及三种配置方式——默认配置、运行配置、配置文件启动

    文章目录 一.初识Redis 1.1 了解Redis 1.2 Redis特性 1.3 Redis使用场景 Redis不适合场景 1.4 用好Redis的建议 1.5 正确安装并启动Redis 在Lin ...

  5. clickhouse数据库删除数据的五种方式

    文章目录 前言 一.通过删除表分区的方式 二.执行delete方式 三.执行truncate方式 四.设置表数据生命周期 五.删除数据文件目录 总结 前言 clickhouse数据库清理数据的方式很多 ...

  6. 架构成长之路:常见的五种MySQL高可用方案分析

    1. 概述 我们在考虑MySQL数据库的高可用的架构时,主要要考虑如下几方面: 如果数据库发生了宕机或者意外中断等故障,能尽快恢复数据库的可用性,尽可能的减少停机时间,保证业务不会因为数据库的故障而中 ...

  7. 精选(36) 常见的五种MySQL高可用方案分析

    来源:https://juejin.im/post/5ca754be6fb9a05e267039a1 1. 概述 我们在考虑MySQL数据库的高可用的架构时,主要要考虑如下几方面: 如果数据库发生了宕 ...

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

    为什么80%的码农都做不了架构师?>>>    最近折腾HTML5游戏需要离线存储功能,便把目前可用的几种HTML5存储方式研究了下,基于HT for Web写了个综合的实例,分别利 ...

  9. Redis_17_Redis服务器中的数据库(五种基本类型底层存放)

    文章目录 一.前言 二.RedisObject对象 2.1 RedisObject对象 2.2 类型type 2.3 编码encoding 2.4 sds 三.字符串对象string 3.1 int编 ...

最新文章

  1. php中条件查询语句,thinkphp3.2框架中where条件查询用法总结
  2. android studio 执行不了,请问,Android studio程序不报错,但是一运行就stop是什原因...
  3. android软件更新模块实现的技术和方法,Android APK签名原理及方法
  4. 获取固件加载基地址的几种方法
  5. 解题报告+优化——试题 基础练习 矩形面积交——16行代码AC
  6. node.js将buffer对象转换为json对象
  7. UIImageView 圆角
  8. 如何把Win11任务栏变窄
  9. (转)Java任务调度框架Quartz入门教程指南(三)任务调度框架Quartz实例详解深入理解Scheduler,Job,Trigger,JobDetail...
  10. java学习--基础知识进阶第五天--API、 Object类 System类、日期相关类、包装类正则表达式...
  11. 为什么c++文件只能执行一次_numba从入门到精通(1)—为什么numba能够加速
  12. 画中画功能的遥控器按键设计
  13. 主成分分析结果成分不显著_数据分析|主成分分析
  14. OkHttp缓存与连接
  15. 网线制作:网线和水晶头的接法
  16. PHP 万能查询代码
  17. 2022-03-26-Subline3的常用快捷键
  18. 四、函数的基本概念和使用
  19. LabVIEW 2013SP1视觉开发必备软件LV、VDM、VBAI、VAS
  20. 【实战】OceanBase之OMS迁移Oracle至oceanbase

热门文章

  1. 记Booking.com iOS开发岗位线上笔试
  2. Android TV开发焦点动作控制小技巧
  3. C#StreamWriter的操作解析
  4. mac下查看tensorboard中的graph
  5. 亲测GO环境搭建,理解go build、go install、go get
  6. DotnetSpider (二) Downloader的设置 Request自定义数据字典
  7. echarts在.Net中使用实例(一) 简单的Demo
  8. ASP.NET中进行消息处理(MSMQ) 三
  9. Go的sync.Cond(四)
  10. wireshark捕获不到东西_好书分享——Wireshark从入门到精通