html5中本機存放區替代cookie:qext.LocalStorage例子

來源:互聯網
上載者:User


背景
先看看各種本機存放區的變革:
Cookies:瀏覽器均支援,容量為4KB
UserData:僅IE支援,容量為64KB
Flash:100KB
Google Gears SQLite :需要外掛程式支援,容量無限制
LocalStorage:HTML5,容量為5M

現準備在項目中試圖取代cookie的實現,基本分析如下:
每次和伺服器端進行互動,cookie都會在請求中被攜帶,cookie過多,也造成頻寬的浪費
cookie的容量很小,或許無法滿足當今互連網的本機存放區需求
在IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+等平台下,已經完全支援HTML5的LocalStorage
在IE7即以下版本中,可以使用UserData來代替cookie,而且同樣比cookie保險
使用者可能清cookie,但不見得知道去清UserData或者LocalStorage,這也增強了一道代碼保險

到底用啥來取代?
UserData:僅IE可用
Flash:儲存空間夠了,也還挺好,可這玩意兒不是HTML原生的
Google Gears:儲存空間沒啥限制,就是得裝額外的外掛程式
HTML5-LocalStorage:官方建議每個網站可以本機存放區5M的內容,非常大了
最後再分析一下現在咱們針對的瀏覽器:IE系列、FF、Chrome、Safari、Opera,外加雙核的遨遊、QQ瀏覽器、搜狗瀏覽器
其中,現在的FF、Chrome、Safari、Opera已經完全支援HTML5-LocalStorage
雙核的那些個瀏覽器,要麼Webkit核心,要麼IE核心(大多都是IE8的核心了),所以這些也是支援HTML5-LocalStorage的
最後就剩IE7及其以下版本,對於專門的IE,就用它們自家提供的UserData了,處理很方便
總結:用UserData和HTML5-LocalStorage結合的方式,來取代cookie!

UserData的儲存情況:
2011-03-23_201627.png
UserData行為通過將資料寫入一個UserData儲存區(UserData store)來儲存資料,userData可以將資料以XML格式儲存在用戶端電腦上。
該資料將一直存在,除非你人為刪除或者用指令碼設定了該資料的失效期。
從上面的表格可以看出,就算是一個受限(Restricted)的網站,單個文檔也能存64KB的資料,整個Domain也能裝得下640KB的東西。

要瞭解更多UserData的東西,可以點擊這裡

關於Expires
我們都知道,採用cookie來進行本機資料緩衝,可以設定一個生命週期,在IE中採用UserData進行替代,能完美的實現。
但是對於HTML5提供的LocalStorage則沒有提供現成的API,來設定某本機存放區的生命週期,只能採取一些極端的手段進行類比實現。

關於資料的批量儲存、提取、刪除
一個好用的組件庫,應該提供更加便捷的API,原生的cookie、UserData、LocalStorage都沒有提供現成的介面可調用,所以,在這裡,我們來封裝一個,使其擁有這樣的批量介面。

代碼實現
1、IE中的UserData實現
原理很簡單,就是建立一個HTML節點,為其增加一個行為(behavior):#default#userData,把待儲存的資料放到該節點的屬性上(setAttribute),再儲存到本地即可(save)。

建立html執行個體:
/**
 * 建立並擷取這個input:hidden執行個體
 * @return {HTMLInputElement} input:hidden執行個體
 * @private
 */
function _getInstance(){
    //把UserData綁定到input:hidden上
    var _input = null;
    //是的,不要驚訝,這裡每次都會建立一個input:hidden並增加到DOM樹種
    //目的是避免資料被重複寫入,提早造成“磁碟空間寫滿”的Exception
    _input = document.createElement("input");
    _input.type = "hidden";
    _input.addBehavior("#default#userData");
    document.body.appendChild(_input);
    return _input;
}
本機資料儲存:
/**
 * 將資料通過UserData的方式儲存到本地,檔案名稱為:檔案名稱為:config.key[1].xml
 * @param {String} key 待儲存資料的key,和config參數中的key是一樣的
 * @param {Object} config 待儲存資料相關配置
 * @cofnig {String} key 待儲存資料的key
 * @config {String} value 待儲存資料的內容
 * @config {String|Object} [expires] 資料的到期時間,可以是數字,單位是毫秒;也可以是日期對象,表示到期時間
 * @private
 */
function __setItem(key,config){
    try {
        var input = _getInstance();
        //建立一個Storage對象
        var storageInfo = config || {};
        //設定到期時間
        if(storageInfo.expires) {
            var expires;
            //如果設定項裡的expires為數字,則表示資料的能存活的毫秒數
            if ('number' == typeof storageInfo.expires) {
                expires = new Date();
                expires.setTime(expires.getTime() + storageInfo.expires);
            }
            input.expires = expires.toUTCString();
        }
                
        //儲存資料
        input.setAttribute(storageInfo.key,storageInfo.value);
        //儲存到本地檔案,檔案名稱為:storageInfo.key[1].xml
        input.save(storageInfo.key);
    } catch (e) {
    }
}

再看userData本機資料的讀取:
/**
 * 提取本機存放區的資料
 * @param {String} config 待擷取的儲存資料相關配置
 * @cofnig {String} key 待擷取的資料的key
 * @return {String} 本機存放區的資料,擷取不到時返回null
 * @example
 * qext.LocalStorage.get({
 *      key : "username"
 * });
 * @private
 */
function _getItem(config){
    try {
        var input = _getInstance();
        //載入本地檔案,檔案名稱為:config.key[1].xml
        input.load(config.key);
        //取得資料
        return input.getAttribute(config.key) || null;
    } catch (e) {
        return null;          
    }
}

類比remove操作:
/**
 * 移除某項儲存資料
 * @param {Object} config 配置參數
 * @cofnig {String} key 待儲存資料的key
 * @private
 */
function _removeItem(config){
    try {
        var input = _getInstance();
        //載入儲存區塊
        input.load(config.key);
        //移除配置項
        input.removeAttribute(config.key);
        //強制使其到期
        var expires = new Date();
        expires.setTime(expires.getTime() - 1);
        input.expires = expires.toUTCString();
        input.save(config.key);
              
        //從allkey中刪除當前key         
        //下面的代碼用來記錄當前儲存的key,便於以後clearAll
        var result = _getItem({key : _clearAllKey});
        if(result) {
            result = result.replace(new RegExp("(^|\\|)" + config.key + "(\\||$)",'g'),'');
            result = {
                key : _clearAllKey,
                value : result
            };
            //儲存鍵
            __setItem(_clearAllKey,result);
        }
              
    } catch (e) {
    }
}

2、再看HTML5-LocalStorage中expires的類比:
在進行資料存放區的時候,單獨多存一個欄位:key + ".expires",如果傳入的expires為數字類型,單位則是毫秒(ms)
window.localStorage.setItem(storageInfo.key,storageInfo.value);
// 如果需要指定生命週期
if(config.expires) {
    var expires;
    //如果設定項裡的expires為數字,則表示資料的能存活的毫秒數
    if ('number' == typeof storageInfo.expires) {
        expires = new Date();
        expires.setTime(expires.getTime() + storageInfo.expires);
    }
 
    window.localStorage.setItem(storageInfo.key + ".expires",expires);
}

在資料讀取的時候,通用讀取這個欄位,判斷時間是否超出了生命週期
result = window.localStorage.getItem(config.key);
//到期時間判斷,如果到期了,則移除該項
if(result) {
    var expires = window.localStorage.getItem(config.key + ".expires");
    result = {
        value : result,
        expires : expires ? new Date(expires) : null
    };
    if(result && result.expires && result.expires < new Date()) {
        result = null;
        window.localStorage.removeItem(config.key);
    }
}

3、提取所有key
/**
 * 擷取所有的本機存放區資料對應的key
 * <pre><code>
 * var keys = qext.LocalStorage.getAllKeys();
 * </code></pre>
 * @return {Array} 所有的key
 */
getAllKeys : function(){
    var result = [];
    //支援本機存放區的瀏覽器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+
    if(_isSupportLocalStorage) {
        var key;
        for(var i = 0,len = window.localStorage.length;i < len;i++){
            key = window.localStorage.key(i);
            if(!/.+\.expires$/.test(key)) {
                result.push(key);
            }
        }
    } else if(_isSupportUserData) { //IE7及以下版本,採用UserData方式
        result = _getAllKeys();
    }
         
    return result;
}

4、清除所有本機存放區的資料
/**
 * 清除所有本機存放區的資料
 * <pre><code>
 * qext.LocalStorage.clearAll();
 * </code></pre>
 */
clearAll : function(){
    //支援本機存放區的瀏覽器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+
    if(_isSupportLocalStorage) {
        window.localStorage.clear();
    } else if(_isSupportUserData) { //IE7及以下版本,採用UserData方式
        _clearAll();
    }
}

關於使用方法
1、資料存放區:qext.LocalStorage.set
// 儲存單個對象到本地
qext.LocalStorage.set({
   key : "username",
   value : "baiduie",
   expires : 3600 * 1000  /*單位:ms*/
});
     
// 儲存多個對象
qext.LocalStorage.set([{
   key : "username",
   value : "baiduie",
   expires : 3600 * 1000  /*單位:ms*/
},{
   key : "password",
   value : "zxlie",
   expires : 3600 * 1000  /*單位:ms*/
}]);

2、資料提取:qext.LocalStorage.get
//擷取某一個本機存放區,傳回值為:{key:"",value:"",expires:""},未取到值時傳回值為:null
 var rst = qext.LocalStorage.get({
    key : "username"
 });
    
 //擷取多個本機存放區,傳回值為:["","",""],未取到值時傳回值為:[null,null,null]
 qext.LocalStorage.get([{
    key : "username"
 },{
    key : "password"
 },{
    key : "sex"
 }]);
3、資料刪除:qext.LocalStorage.remove
//刪除一個本機存放區項
qext.LocalStorage.remove({
    key : "username"
});
    
//刪除多個本機存放區項目
qext.LocalStorage.remove([{
    key : "username"
},{
    key : "password"
},{
    key : "sex"
}]);
4、清空所有資料:qext.LocalStorage.clearAll
// 清空所有本機存放區的資料
qext.LocalStorage.clearAll();
5、擷取所有本機存放區的key:qext.LocalStorage.getAllKes
// 擷取所有本機存放區的key
var keys = qext.LocalStorage.getAllKeys();

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.