歷史
在HTML5本地存儲以前,若是咱們想在客戶端保存持久化數據,有這麼幾個選擇:
html
現狀
咱們如今一般所說的HTML5本地存儲,通常指的是Web Storage規範,這個標準曾經是HTML5規範的一部分,但後來由於種種緣由從HTML5規範中分離了出來。可是除了Web Storage,HTML5的本地存儲標準還有另外2個競爭者:Web SQL Database和IndexedDB。下面就讓咱們依次來看看這3個規範吧。 html5
Web Storage
Web Storage是目前獲得支持最普遍的HTML5本地存儲規範:IE 8+、FF 3.5+、Safari 4+、Chrome 4+、Opera 10.5+,以及iPhone 2+和Android 2+都已經支持Web Storage,要判斷你的瀏覽器是否支持Web Storage,可使用下面這個函數: web
function supports_html5_storage() { try { return 'localStorage' in window && window['localStorage'] !== null; } catch (e) { return false; } }
HTML5 Storage的使用很是簡單: sql
var foo = localStorage.getItem("bar"); // ... localStorage.setItem("bar", foo);
你也能夠寫成下面這樣:數據庫
var foo = localStorage["bar"];
// ...
localStorage["bar"] = foo;
若是要將某個key從存儲空間刪除,能夠調用removeItem:後端
localStorage.removeItem('foo');
你也能夠像遍歷數組那樣遍歷存儲的全部鍵值對象: api
for(var i=0; ivar key = localStorage.key(i); console.log(key + ":" + localStorage[key]); }
若是你的程序須要在不一樣頁面訪問同一個值,你可能須要瞭解這個值是否已經被其餘頁面改變了,這能夠經過向瀏覽器註冊storage事件來實現:數組
window.addEventListener('storage', function(e) { console.log(e.key + "'s value is changed from '" + e.oldValue + "' to '" + e.newValue + "' by " + e.url); }, false); //A頁面 localStorage['foo'] = 'bar'; //B頁面 localStorage['foo'] = 'newBar';
這時你應該會在A頁面的Console中看到:
foo’s value is changed from ‘bar’ to ‘newbar’ by http://localhost/test.html
要注意的是,storage事件僅僅只是通知你某個鍵對應的值已經發生了改變,你沒有辦法在回調中阻止這個改變發生。
HTML5 Storage看起來不錯,那它有沒什麼缺點呢?好問題。要說HTML5 Storage的缺點,惟一的問題就是它默認的QUOTA只有5MB,而且你沒辦法經過程序自行或是提示用戶來增長存儲空間。惟一的辦法就是用戶本身打開 瀏覽器的設置,並手動修改QUOTA的大小,若是超出了5MB的限制,你將會遇到一個「QUOTA_EXCEEDED_ERR」的錯誤。
Web SQL Database
Web SQL Database是一個已經廢棄的規範,可是鑑於除了IE和Firefox,其餘瀏覽器都已經實現了Web SQL Database,而且它還具備一些HTML5 Storage所不具備的特性,因此仍是值得了解一下的。
Web SQL Database就像它的名字那樣,就是一個讓你能夠在Web上直接使用的SQL數據庫,你要作的就是打開數據庫,而後執行SQL,和你對Mysql作的事情沒什麼兩樣: 瀏覽器
openDatabase('documents', '1.0', 'Local document storage', 5*1024*1024, function (db) { db.changeVersion('', '1.0', function (t) { t.executeSql('CREATE TABLE docids (id, name)'); }, error); });
關於Web SQL Database的更多介紹,能夠參看這篇指南。
可是它的缺點也一樣明顯。最大的問題就出在SQL上,實際上並不存在一種叫作SQL的標準結構化查詢語言,咱們日常使用的其實是MS SQL、Oracle SQL、MySQL SQL、postgre SQL或者SQLite SQL(儘管有一個叫作SQL-92的規範,但它基本形同虛設),更進一步,甚至都不存在SQLite SQL,咱們使用的其實是SQLite x.y.z SQL,而這也就是Web SQL Database最大的問題,它沒法統一各個瀏覽器廠商實現的SQL語言,若是你的某條Web SQL查詢只能在Chrome上運行,這還能叫作標準嗎?
因此,若是你如今訪問Web SQL Database的規範頁面,你會在頂部看到這樣一則聲明:
這個規範已經陷入了一個僵局:目前的全部實現都是基於同一個SQL後端(SQLite),可是咱們須要更多的獨立實現來完成標準化,因此除非有廠商願意獨立實現這個規範,不然當前的SQL規範只能採用SQLite的SQL方言,而做爲一個標準,這是不可接受的。
IndexedDB
最後咱們要介紹的就是IndexedDB了,相比其餘兩個規範,目前只有Firefox實現了IndexedDB(順便提一下,Mozilla表示它們永遠不會去實現Web SQL Database),不過Google已經表示正在考慮在Chrome中加入IndexDB支持。
IndexedDB引入了一個object store的概念,這有點像是一個SQL Database,你能夠在「數據庫」中存儲「記錄」,而且每條「記錄」能夠擁有不少「字段",每一個字段都有一個特定的數據類型,你能夠選擇記錄的子集, 並使用「光標」進行遍歷,同時object store中的全部變動都是基於「事務」的。
下面讓咱們來看一個小例子: 服務器
var request = window.indexedDB.open("CandyDB", "My candy store database"); request.onsuccess = function(event) { var db = event.result; if (db.version != "1") { // User's first visit, initialize database. var createdObjectStoreCount = 0; var objectStores = [ { name: "kids", keyPath: "id", autoIncrement: true }, { name: "candy", keyPath: "id", autoIncrement: true }, { name: "candySales", keyPath: "", autoIncrement: true } ]; function objectStoreCreated(event) { if (++createdObjectStoreCount == objectStores.length) { db.setVersion("1").onsuccess = function(event) { loadData(db); }; } } for (var index = 0; index < objectStores.length; index++) { var params = objectStores[index]; request = db.createObjectStore(params.name, params.keyPath, params.autoIncrement); request.onsuccess = objectStoreCreated; } } else { // User has been here before, no initialization required. loadData(db); } };
關於Indexed的更多介紹能夠參看Mozilla Blog的這篇指南。
--------
本文編譯整理自:Mark Pilgrim的Dive Into HTML5 第七章 HTML5本地存儲,靈感來自於 ProcessOn 已經支持多頁面文件元素複製粘貼 編譯:@yuanyiz。