HTML5数据库建模,HTML5的五种客户端离线存储方案
最近折腾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的五种客户端离线存储方案相关推荐
- 深度点评五种常见WiFi搭建方案
总结十年无线搭建经验,针对企业常见的五种办公室无线网络方案做个简要分析,各种方案有何优劣,又适用于那种类型的企业. 方案一:仅路由器或AP覆盖 简述:使用路由器或AP覆盖多个无线盲区,多个AP的部署实 ...
- 常见html5营销类型有哪些,五种常见的营销策略
网络营销的成功往往在于策略.给大家介绍几个在策略中经常用的方式. 1.折扣营销 折扣营销策略简单说就是给产品打折,这是常用的促销方式,折扣营销,迎合了消费者少花钱的心理,所以,这一方式在销售上也是比较 ...
- 四种有能力取代Cookies的客户端Web存储方案
目前在用户的网络浏览器中保存大量数据需要遵循几大现有标准,每一种标准都拥有自己的优势.短板.独特的W3C标准化状态以及浏览器支持级别.但无论如何,这些标准的实际表现都优于广泛存在的cookies机制. ...
- 【数据库Redis】Redis五种基本数据结构以及三种配置方式——默认配置、运行配置、配置文件启动
文章目录 一.初识Redis 1.1 了解Redis 1.2 Redis特性 1.3 Redis使用场景 Redis不适合场景 1.4 用好Redis的建议 1.5 正确安装并启动Redis 在Lin ...
- clickhouse数据库删除数据的五种方式
文章目录 前言 一.通过删除表分区的方式 二.执行delete方式 三.执行truncate方式 四.设置表数据生命周期 五.删除数据文件目录 总结 前言 clickhouse数据库清理数据的方式很多 ...
- 架构成长之路:常见的五种MySQL高可用方案分析
1. 概述 我们在考虑MySQL数据库的高可用的架构时,主要要考虑如下几方面: 如果数据库发生了宕机或者意外中断等故障,能尽快恢复数据库的可用性,尽可能的减少停机时间,保证业务不会因为数据库的故障而中 ...
- 精选(36) 常见的五种MySQL高可用方案分析
来源:https://juejin.im/post/5ca754be6fb9a05e267039a1 1. 概述 我们在考虑MySQL数据库的高可用的架构时,主要要考虑如下几方面: 如果数据库发生了宕 ...
- HTML5 Web 客户端五种离线存储方式汇总
为什么80%的码农都做不了架构师?>>> 最近折腾HTML5游戏需要离线存储功能,便把目前可用的几种HTML5存储方式研究了下,基于HT for Web写了个综合的实例,分别利 ...
- Redis_17_Redis服务器中的数据库(五种基本类型底层存放)
文章目录 一.前言 二.RedisObject对象 2.1 RedisObject对象 2.2 类型type 2.3 编码encoding 2.4 sds 三.字符串对象string 3.1 int编 ...
最新文章
- php中条件查询语句,thinkphp3.2框架中where条件查询用法总结
- android studio 执行不了,请问,Android studio程序不报错,但是一运行就stop是什原因...
- android软件更新模块实现的技术和方法,Android APK签名原理及方法
- 获取固件加载基地址的几种方法
- 解题报告+优化——试题 基础练习 矩形面积交——16行代码AC
- node.js将buffer对象转换为json对象
- UIImageView 圆角
- 如何把Win11任务栏变窄
- (转)Java任务调度框架Quartz入门教程指南(三)任务调度框架Quartz实例详解深入理解Scheduler,Job,Trigger,JobDetail...
- java学习--基础知识进阶第五天--API、 Object类 System类、日期相关类、包装类正则表达式...
- 为什么c++文件只能执行一次_numba从入门到精通(1)—为什么numba能够加速
- 画中画功能的遥控器按键设计
- 主成分分析结果成分不显著_数据分析|主成分分析
- OkHttp缓存与连接
- 网线制作:网线和水晶头的接法
- PHP 万能查询代码
- 2022-03-26-Subline3的常用快捷键
- 四、函数的基本概念和使用
- LabVIEW 2013SP1视觉开发必备软件LV、VDM、VBAI、VAS
- 【实战】OceanBase之OMS迁移Oracle至oceanbase
热门文章
- 记Booking.com iOS开发岗位线上笔试
- Android TV开发焦点动作控制小技巧
- C#StreamWriter的操作解析
- mac下查看tensorboard中的graph
- 亲测GO环境搭建,理解go build、go install、go get
- DotnetSpider (二) Downloader的设置 Request自定义数据字典
- echarts在.Net中使用实例(一) 简单的Demo
- ASP.NET中进行消息处理(MSMQ) 三
- Go的sync.Cond(四)
- wireshark捕获不到东西_好书分享——Wireshark从入门到精通