1. Web SQL Database
HTML5的存儲(chǔ)還有一種Web SQL Database方式淮摔,雖然還有瀏覽器支持,是唯一的關(guān)系數(shù)據(jù)庫結(jié)構(gòu)的存儲(chǔ)始赎,但W3C以及停止對其的維護(hù)和發(fā)展和橙,所以這里我們也不再對其進(jìn)行介紹:Beware. This specification is no longer in active maintenance and the Web Applications Working Group does not intend to maintain it further.
整個(gè)示例主要就是將HT for Web的DataModel數(shù)據(jù)模型信息進(jìn)行序列化和反序列化,這個(gè)過程很簡單通過dataModel.serialize()將模型序列化成JSON字符串造垛,通過dataModel.deserialize(jsonString)將JSON字符串內(nèi)存反序列化出模型信息魔招,而存儲(chǔ)主要就是主要就是針對JSON字符串進(jìn)行操作。
2. LocalStorage
先介紹最簡單的存儲(chǔ)方式LocalStorage五辽,代碼如下办斑,幾乎不用介紹就是Key-Value的簡單鍵值對存儲(chǔ)結(jié)構(gòu),Web Storage除了localStorage的持久性存儲(chǔ)外杆逗,還有針對本次回話的sessionStorage方式乡翅,一般情況下localStorage較為常用。
這兩種存儲(chǔ)方式的API也一樣罪郊,詳細(xì)說明可以自行百度蠕蚜。
獲取某一條:localStorage.getItem("key")、sessionStorage.getItem("key");
存儲(chǔ)某一條:localStorage.setItem("key", value)悔橄、sessionStorage.setItem("key", value);
刪除某一條:localStorage.removeItem("key")波势、sessionStorage.removeItem("key");
刪除所有:localStorage.clear()翎朱、sessionStorage.clear();
3. Cookie
最古老的存儲(chǔ)方式為Cookie,本例中我只能保存一個(gè)圖元的信息尺铣,這種存儲(chǔ)方式存儲(chǔ)內(nèi)容很有限拴曲,只適合做簡單信息存儲(chǔ),存取接口設(shè)計(jì)得極其反人類凛忿,為了介紹HTML5存儲(chǔ)方案的完整性我順便把他給列上:
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";
}
}
4. Indexed Database API
如今比較實(shí)用強(qiáng)大的存儲(chǔ)方式為Indexed Database API澈灼,IndexedDB可以存儲(chǔ)結(jié)構(gòu)對象,可構(gòu)建key和index的索引方式查找店溢,目前各瀏覽器的已經(jīng)逐漸支持IndexedDB的存儲(chǔ)方式叁熔,其使用代碼如下,需注意IndexedDB的很多操作接口類似NodeJS的異步回調(diào)方式床牧,特別是查詢時(shí)連cursor的continue都是異步再次回調(diào)onsuccess函數(shù)的操作方式荣回,因此和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');
}
};
}
5. FileSystem API
最后是FileSystem API相當(dāng)于操作本地文件的存儲(chǔ)方式戈咳,目前支持瀏覽器不多心软,其接口標(biāo)準(zhǔn)也在發(fā)展制定變化中,例如在我寫這個(gè)代碼時(shí)大部分文獻(xiàn)使用的webkitStorageInfo已被navigator.webkitPersistentStorage和navigator.webkitTemporaryStorage替代著蛙,存儲(chǔ)的文件可通過filesystem的URL方式在chrome瀏覽器中查找到删铃,甚至可通過filesy類似目錄的訪問,因此也可以動(dòng)態(tài)生成圖片到本地文件踏堡,然后通過filesystem:http:***的URL方式直接賦值給img的html元素的src訪問猎唁,因此本地存儲(chǔ)打開了一扇新的門,相信以后會(huì)冒出更多稀奇古怪的奇葩應(yīng)用顷蟆。
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');
});
});
}
6. 其他
Browser-Side的存儲(chǔ)方式還在快速的發(fā)展中诫隅,其實(shí)除了以上幾種外還有Application Cache,相信將來還會(huì)有新秀出現(xiàn)帐偎,雖然“云”是大趨勢阎肝,但客戶端并非要走極端的“瘦”方案,這么多年冒出了這么多客戶端存儲(chǔ)方式肮街,說明讓客戶端更強(qiáng)大的市場需求是強(qiáng)烈的风题,當(dāng)然目前動(dòng)蕩階段苦逼的是客戶端程序員,除了要適配Mouse和Touch嫉父,還要適配各種屏沛硅,如今還得考慮適配各種存儲(chǔ),希望本文能在大家選型客戶端存儲(chǔ)方案時(shí)有點(diǎn)幫助绕辖。
關(guān)注公眾號【grain先森】摇肌,回復(fù)關(guān)鍵詞 【18福利】,獲取為你準(zhǔn)備的年終福利仪际,更多關(guān)鍵詞玩法期待你的探索~