HTML5的五種客戶端離線儲存方案
最近折騰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.
整個示例主要就是將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,本例中我只能儲存一個圖元的資訊,這種儲存方式儲存內容很有限,只適合做簡單資訊儲存,存取介面設計得極其反人類,為了介紹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`);
});
});
}
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
相關文章
- HTML5 Web 客戶端五種離線儲存方式彙總HTMLWeb客戶端
- HTML5離線應用與客戶端儲存HTML客戶端
- 四種有能力取代Cookies的客戶端Web儲存方案Cookie客戶端Web
- 客戶端儲存筆記客戶端筆記
- 客戶端儲存那些事客戶端
- 客戶端資料儲存概述客戶端
- GRpc新增客戶端的五種方式RPC客戶端
- 《客戶端儲存技術》總結客戶端
- 利用Node實現HTML5離線儲存HTML
- HTML5離線儲存原理及實現HTML
- 《客戶端儲存技術》讀後感客戶端
- 在客戶端儲存對EJB的遠端呼叫是否可行?客戶端
- 萌新必看——10種客戶端儲存哪家強,一文讀盡!客戶端
- MySQL client客戶端的四種連線方式MySqlclient客戶端
- Html5 Web的5中離線儲存方式之localStorageHTMLWeb
- 10種相親交友原始碼客戶端儲存方式,各有優缺點原始碼客戶端
- 超越 Cookie:當今的客戶端資料儲存技術Cookie客戶端
- oracle客戶端連線server 端, tnsnames的三種設定方式Oracle客戶端Server
- HTML5離線儲存Manifest原理及使用詳解HTML
- HTML5學習之離線儲存基礎知識HTML
- 客戶端(瀏覽器端)資料儲存技術概覽客戶端瀏覽器
- 離線儲存manifest
- 表格儲存技術方案實踐及客戶案例分享
- Java五種儲存位置Java
- impala客戶端連線客戶端
- Redis客戶端連線Redis客戶端
- 庫存管理軟體可提高客戶滿意度的五種方式
- Spring 客戶端 IP 地址獲取及儲存細節Spring客戶端
- Asp.net直接儲存(下載)檔案到客戶端ASP.NET客戶端
- 【物件儲存】Minio本地執行和 golang客戶端基本操作物件Golang客戶端
- 突破本地離線儲存的JS庫 localforageJS
- Mozilla 希望剝離 Thunderbird 郵件客戶端客戶端
- mysql、redis 客戶端連線池MySqlRedis客戶端
- vncserver建立與客戶端連線VNCServer客戶端
- 技術週刊(2019-01-14 客戶端儲存 )客戶端
- OSSEC服務端配置客戶端批次部署方案服務端客戶端
- 客戶端連線資料庫的方法客戶端資料庫
- 客戶端本地儲存的比較及使用window.name資料傳輸客戶端