web前端實現本機存放區

來源:互聯網
上載者:User

標籤:style   blog   http   color   io   os   使用   ar   java   

  當我們在提及web前端本機存放區的時候,首先需要介紹一下本地化儲存的概念和曆史。本地化儲存從來不是一個新奇的概念,因為web應用程式一直在追求的就是媲美甚至超越傳統型應用程式。但是傳統型應用程式一直優於web應用程式一個很重要的原因是它的本地化儲存得到了很好的支援。對於本地應用程式,作業系統會提供一個抽象層,用於儲存和擷取特定於應用程式的資料,這些資料可以儲存於註冊表、INI檔案,或者其他什麼地方,這取決於作業系統的實現,如果本地應用程式需要不單是索引值對形式的本機存放區,可以使用嵌入式資料庫或其他很多種解決方案。而對於web應用程式,它的本機存放區一步一步走到今天的HTML5本機存放區是非常不容易的。為了描述它的曆史,我們可以先看一張圖片:

  從圖片可以看出,無論是從儲存資料的大小還是相容性來看,web前端本機存放區都走得不容易。在著重介紹HTML5本機存放區之前,我們先來看一看前面幾個儲存方式的概念。

  HTTP cookie:HTTP cookie的缺點很明顯,最多隻能儲存4KB的資料,每個HTTP請求都會被傳送回伺服器,明文傳輸(除非你使用SSL)。

  IE userData:userData是微軟在上世紀90年代的瀏覽器大戰時推出的本機存放區方案,藉助DHTML的behaviour屬性來儲存本機資料, 允許每個頁面最多儲存64K資料,每個網站最多640K資料,userData的缺點顯而易見,它不是Web標準的一部分,除非你的程式只需要支援IE, 否則它基本沒什麼用處。

  Flash cookie:Flash cookie的名字有些誤導,它實際上和HTTP cookie並不是一回事,或許它的名字應該叫做"Flash本機存放區”,Flash cookie預設允許每個網站儲存不超過100K的資料,如果超出了,Flash會自動向使用者請求更大的儲存空間,藉助Flash的 ExternalInterface介面,你可以很輕鬆地通過Javascript操作Flash的本機存放區。Flash的問題很簡單,就是因為它是 Flash。

  Google Gears:Gears是Google在07年發布的一個開源瀏覽器外掛程式,旨在改進各大瀏覽器的相容性,Gears內建了一個基於SQLite的嵌入式 SQL資料庫,並提供了統一API對資料庫進行訪問,在取得使用者授權之後,每個網站可以在SQL資料庫中儲存不限大小的資料,Gears的問題就是 Google自己都已經不用它了。

  從上面的簡介我們可以看出,在以前,本機存放區面臨的主要問題是,對於儲存容量較大的方式,需要特定的外掛程式支援;對於不需要外掛程式支援的儲存方式,則處於安全問題或者大小限制而遭到扼殺。在這種雙重的矛盾面前,HTML5本機存放區橫空出世,對於前端開發人員是一種巨大的福音。

  所謂的HTML5本機存放區更精確的說法應該是DOM儲存。根據MDN的定義,DOM儲存的機制是通過儲存字串類型的鍵/值對,來提供一種安全的存取方式.這個附加功能的目標是提供一個全面的,可以用來建立互動式應用程式的方法(包括那些進階功能,例如可以離線工作一段時間)。

  HTML5的DOM儲存分成兩種:SessionStorage和LocalStorage。在當代瀏覽器中的相容性如下:

     

  中提及的globalStorage是非標準的,已經廢棄,在這裡我們直接忽略它。而sessionStorage和localStorage在絕大部分現代瀏覽器中已經得到了很好的支援,但是既然是絕大部分,就必須照顧那些還不支援這兩個對象的瀏覽器。為了檢測瀏覽器是否支援這兩個對象,我們可以簡單的用下面的代碼來檢測:

1 function storageSupport() {  2         try {  3             return ‘localStorage‘ in window && window[‘localStorage‘] !== null;  4         } catch (e) {  5             return false;  6         }  7 }

  非常幸運的是,這兩種對象的使用方式都非常簡單,這裡借用網上 的一張圖:

     

  首先我們來看一看sessionStorage,sessionStorage 是個全域對象,它維護著在頁面會話(page session)期間有效儲存空間。只要瀏覽器開著,頁面會話周期就會一直持續。當頁面重新載入(reload)或者被恢複(restores)時,頁面會話也是一直存在的。每在新標籤或者新視窗中開啟一個新頁面,都會初始化一個新的會話。這句話看起來比較抽象,我們直接看一個demo:

1 var name = sessionStorage.setItem("myname","yuanzm");2 alert(sessionStorage.getItem("myname"));

  當我們在瀏覽器中開啟的時候,就會快顯視窗,顯示“yuanzm”,然後我們按F12鍵,查看瀏覽器的調試視窗:

  

  我們能夠發現,在瀏覽器的本機存放區sessionStorage中已經有了key值為“myname”的項。這個時候,重新整理頁面,仍然會彈出“yuanzm”,因為如果不調用sessionStorage.removeItem()或者手動清除這個項的話,這個項將一直存在。而上面提到的“只要瀏覽器開著,頁面會話周期就會一直持續。當頁面重新載入(reload)或者被恢複(restores)時,頁面會話也是一直存在的。每在新標籤或者新視窗中開啟一個新頁面,都會初始化一個新的會話”的意思是說,如果我們不重新設定myname的值,在新開啟一個瀏覽器標籤或者再次開啟一個瀏覽器視窗的時候,這個值是不存在的,也就是null。為了驗證這一點,很簡單,我們把上面兩行代碼的第一行注釋掉,然後重新整理頁面,接著在新的瀏覽器標籤中開啟這個檔案。這兩個動作分別會產生什麼效果呢?答案很簡單,當再次重新整理頁面的時候,仍然會彈出“yuanzm”,因為這個資料已經儲存在本地了,而修改代碼之後在新的頁面開啟,得到的結果是null,因為當前頁面會話中沒有“myname”這個值。

  接下來我們看一看localStorage,他是跨多個視窗,且持續範圍可超過當前會話;意味著當瀏覽器關閉再重新開啟,資料依然是可用的;拿上面的例子來說,當修改代碼之後,在新的標籤開啟頁面,仍然會彈出“yuanzm”,我們再次在瀏覽器中查看效果:

  

  由於這兩個對象的使用很簡單,暫時就介紹到這裡。下面還需要介紹一下的就是相容性問題。原因很簡單,因為並不是所有的瀏覽器都支援這兩個對象。這裡的相容包括兩種,第一種是在沒有原生支援localStorage的瀏覽器中使用,第二種是相容不同瀏覽器對於這兩種用法的差異。對於第一種,MDN給出了相容代碼:

if (!window.localStorage) {  Object.defineProperty(window, "localStorage", new (function () {    var aKeys = [], oStorage = {};    Object.defineProperty(oStorage, "getItem", {      value: function (sKey) { return sKey ? this[sKey] : null; },      writable: false,      configurable: false,      enumerable: false    });    Object.defineProperty(oStorage, "key", {      value: function (nKeyId) { return aKeys[nKeyId]; },      writable: false,      configurable: false,      enumerable: false    });    Object.defineProperty(oStorage, "setItem", {      value: function (sKey, sValue) {        if(!sKey) { return; }        document.cookie = escape(sKey) + "=" + escape(sValue) + "; path=/";      },      writable: false,      configurable: false,      enumerable: false    });    Object.defineProperty(oStorage, "length", {      get: function () { return aKeys.length; },      configurable: false,      enumerable: false    });    Object.defineProperty(oStorage, "removeItem", {      value: function (sKey) {        if(!sKey) { return; }        var sExpDate = new Date();        sExpDate.setDate(sExpDate.getDate() - 1);        document.cookie = escape(sKey) + "=; expires=" + sExpDate.toGMTString() + "; path=/";      },      writable: false,      configurable: false,      enumerable: false    });    this.get = function () {      var iThisIndx;      for (var sKey in oStorage) {        iThisIndx = aKeys.indexOf(sKey);        if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); }        else { aKeys.splice(iThisIndx, 1); }        delete oStorage[sKey];      }      for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); }      for (var iCouple, iKey, iCouplId = 0, aCouples = document.cookie.split(/\s*;\s*/); iCouplId < aCouples.length; iCouplId++) {        iCouple = aCouples[iCouplId].split(/\s*=\s*/);        if (iCouple.length > 1) {          oStorage[iKey = unescape(iCouple[0])] = unescape(iCouple[1]);          aKeys.push(iKey);        }      }      return oStorage;    };    this.configurable = false;    this.enumerable = true;  })());}
View Code

  至於第二種,在github上面有很多優秀的代碼,博主這裡推薦其中一份:github localStorage

   最後,歡迎轉載原文,但是希望加上轉載連結:http://www.cnblogs.com/yuanzm/p/4023295.html

web前端實現本機存放區

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.