HTML5本地存儲不完全指南

作者: Yuanyi Zhang  發布時間: 2011-10-13 11:43  閱讀: 3441 次  推薦: 0   原文鏈接   [收藏]  
摘要:本文將為您詳細講述HTML5的本地存儲。

  歷史

  在HTML5本地存儲之前,如果我們想在客戶端保存持久化數據,有這么幾個選擇:

  1. HTTP cookie,HTTP cookie的缺點很明顯,最多只能存儲4KB的數據,每個HTTP請求都會被傳送回服務器,明文傳輸(除非你使用SSL)。
  2. IE userData,userData是微軟在上世紀90年代的瀏覽器大戰時推出的本地存儲方案,借助DHTML的behaviour屬性來存儲本地數據,允許每個頁面最多存儲64K數據,每個站點最多640K數據,userData的缺點顯而易見,它不是web標準的一部分,除非你的程序只需要支持IE,否則它基本沒什么用處。
  3. Flash cookie,Flash cookie的名字有些誤導,它實際上和HTTP cookie并不是一回事,或許它的名字應該叫做Flash本地存儲,Flash cookie默認允許每個站點存儲不超過100K的數據,如果超出了,Flash會自動向用戶請求更大的存儲空間,借助Flash的ExternalInterface接口,你可以很輕松的通過Javascript操作Flash的本地存儲,Flash的問題很簡單,就是因為它是Flash。
  4. Google Gears,Gears是Google在07年發布的一個開源瀏覽器插件,旨在改進各大瀏覽器的兼容性,Gears內置了一個基于SQLite的嵌入式SQL數據庫,并提供了統一API對數據庫進行訪問,在取得用戶授權之后,每個站點可以在SQL數據庫中存儲不限大小的數據,Gears的問題就是Google自己都已經不用它了。

  現狀

  我們現在通常所說的HTML5本地存儲,一般指的是Web Storage規范,這個標準曾經是HTML5規范的一部分,但后來因為種種原因從HTML5規范中分離了出來,但是除了Web Storage,HTML5的本地存儲標準還有另外2個競爭者:Web SQL Database和IndexedDB,下面就讓我們依次來看看這3個規范吧。

  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,可以使用下面這個函數:

function supports_html5_storage() {
    
try {
         
return 'localStorage' in window && window['localStorage'] !== null;
     }
catch (e) {
         
return false;
     }
}

  HTML5 Storage的使用非常簡單:

var foo = localStorage.getItem("bar");
// ...
localStorage.setItem("bar", foo);

  你也可以寫成下面這樣:

var foo = localStorage["bar"];
// ...
localStorage["bar"] = foo;

  如果要將某個key從存儲空間刪除,可以調用removeItem:

localStorage.removeItem('foo');

  你也可以像遍歷數組那樣遍歷存儲的所有鍵值對象:

for(var i=0; i< localStorage.length; i++){
    var 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中看到:

  foos 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 PilgrimDive Into HTML5 第七章 HTML5本地存儲

  編譯:@yuanyiz

  轉載請遵照 CC-BY-3.0協議

0
0
 
標簽:HTML5
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()