目前使用比較多的本地存儲方案有比如Flash SharedObject、Google Gears、Cookie、LocalStorage、User Data、Open Database等方案。綜合比較了下,最終選擇了LocalStorage。
關於他們之間的比較,我在此不多說了,本文着重實現。想了解他們之間的區別的朋友可以參考一下這幾個園友博客:
1.JavaScript本地存儲實踐: http://www.cnblogs.com/xupeiyu/p/4447443.html
2.HTML5 LocalStorage 本地存儲:http://www.cnblogs.com/xiaowei0705/archive/2011/04/19/2021372.html
這里是用UserData和HTML5-LocalStorage結合的方式,來取代cookie。參考修改了alien朋友的LocalStorage.js,<<傳送門>>
做個簡單的比較:
UserData:僅IE可用
Flash:存儲空間大
Google Gears:存儲空間沒限制,需裝額外的插件
HTML5-LocalStorage:官方建議每個站點可以本地存儲5M的內容
原本的js我進行了些修改,如下:
Namespace = new Object(); // 全局對象僅僅存在register函數,參數為名稱空間全路徑,如"Grandsoft.GEA" Namespace.register = function(fullNS) { // 將命名空間切成N部分, 比如Grandsoft、GEA等 var nsArray = fullNS.split('.'); var sEval = ""; var sNS = ""; for (var i = 0; i < nsArray.length; i++) { if (i != 0) sNS += "."; sNS += nsArray[i]; // 依次創建構造命名空間對象(假如不存在的話)的語句 // 比如先創建Grandsoft,然后創建Grandsoft.GEA,依次下去 sEval += "if (typeof(" + sNS + ") == 'undefined') " + sNS + " = new Object();" } if (sEval != "") eval(sEval); } /** * 注冊命名空間 */ Namespace.register('SummitLocalStorage'); /** * @class SummitLocalStorage.LocalStorage * 跨瀏覽器的本地存儲實現。高級瀏覽器使用localstorage,ie使用UserData。雖然說是本地存儲,也請不要存儲過大數據,最好不要大於64K. * 因為ie下UserData每頁最大存儲是64k。 * @singleton * @author zhaoxianlie (xianliezhao@foxmail.com) */ (function() { /** * 驗證字符串是否合法的鍵名 * @param {Object} key 待驗證的key * @return {Boolean} true:合法,false:不合法 * @private */ function _isValidKey(key) { return (new RegExp("^[^\\x00-\\x20\\x7f\\(\\)<>@,;:\\\\\\\"\\[\\]\\?=\\{\\}\\/\\u0080-\\uffff]+\x24")).test(key); } //所有的key var _clearAllKey = "_baidu.ALL.KEY_"; /** * 創建並獲取這個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的方式保存到本地,文件名為:文件名為: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) { //保存有效內容 __setItem(key, config); //下面的代碼用來記錄當前保存的key,便於以后clearAll var result = _getItem({ key: _clearAllKey }); if (result) { result = { key: _clearAllKey, value: result }; } else { result = { key: _clearAllKey, value: "" }; } if (!(new RegExp("(^|\\|)" + key + "(\\||$)", 'g')).test(result.value)) { result.value += "|" + key; //保存鍵 __setItem(_clearAllKey, result); } } /** * 提取本地存儲的數據 * @param {String} config 待獲取的存儲數據相關配置 * @cofnig {String} key 待獲取的數據的key * @return {String} 本地存儲的數據,獲取不到時返回null * @example * SummitLocalStorage.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; } } /** * 移除某項存儲數據 * @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) {} } //移除所有的本地數據 function _clearAll() { result = _getItem({ key: _clearAllKey }); if (result) { var allKeys = result.split("|"); var count = allKeys.length; for (var i = 0; i < count; i++) { if (!!allKeys[i]) { _removeItem({ key: allKeys[i] }); } } } } /** * 獲取所有的本地存儲數據對應的key * @return {Array} 所有的key * @private */ function _getAllKeys() { var result = []; var keys = _getItem({ key: _clearAllKey }); if (keys) { keys = keys.split('|'); for (var i = 0, len = keys.length; i < len; i++) { if (!!keys[i]) { result.push(keys[i]); } } } return result; } /** * 判斷當前瀏覽器是否支持本地存儲:window.localStorage * @return {Boolean} true:支持;false:不支持 * @remark 支持本地存儲的瀏覽器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+ * @private var _isSupportLocalStorage = (('localStorage' in window) && (window['localStorage'] !== null)), _isSupportUserData = !!jQuery.browser.ie; */ var _isSupportLocalStorage = (('localStorage' in window) && (window['localStorage'] !== null)); SummitLocalStorage.LocalStorage = { /** * 如果支持本地存儲,返回true;否則返回false * @type Boolean */ isAvailable: _isSupportLocalStorage || _isSupportUserData, /** * 將數據進行本地存儲(只能存儲字符串信息) * <pre><code> * //保存單個對象 * SummitLocalStorage.LocalStorage.set({ * key : "username", * value : "baiduie", * expires : 3600 * 1000 * }); * //保存對個對象 * SummitLocalStorage.LocalStorage.set([{ * key : "username", * value : "baiduie", * expires : 3600 * 1000 * },{ * key : "password", * value : "zxlie", * expires : 3600 * 1000 * }]); * </code></pre> * @param {Object} obj 待存儲數據相關配置,可以是單個JSON對象,也可以是由多個JSON對象組成的數組 * <ul> * <li><b>key</b> : String <div class="sub-desc">待存儲數據的key,務必將key值起的復雜一些,如:baidu.username</div></li> * <li><b>value</b> : String <div class="sub-desc">待存儲數據的內容</div></li> * <li><b>expires</b> : String/Object (Optional)<div class="sub-desc">數據的過期時間,可以是數字,單位是毫秒;也可以是日期對象,表示過期時間</div></li> * </ul> */ set: function(obj) { //保存單個對象 var _set_ = function(config) { //key校驗 if (!_isValidKey(config.key)) { return; } //待存儲的數據 var storageInfo = config || {}; //支持本地存儲的瀏覽器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+ if (_isSupportLocalStorage) { 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); } } else if (_isSupportUserData) { //IE7及以下版本,采用UserData方式 _setItem(config.key, storageInfo); } }; //判斷傳入的參數是否為數組 if (obj && obj.constructor === Array && obj instanceof Array) { for (var i = 0, len = obj.length; i < len; i++) { _set_(obj[i]); } } else if (obj) { _set_(obj); } }, /** * 提取本地存儲的數據 * <pre><code> * //獲取某一個本地存儲,返回值為:{key:"",value:"",expires:""},未取到值時返回值為:null * var rst = SummitLocalStorage.LocalStorage.get({ * key : "username" * }); * //獲取多個本地存儲,返回值為:["","",""],未取到值時返回值為:[null,null,null] * SummitLocalStorage.LocalStorage.get([{ * key : "username" * },{ * key : "password" * },{ * key : "sex" * }]); * </code></pre> * @param {String} obj 待獲取的存儲數據相關配置,支持單個對象傳入,同樣也支持多個對象封裝的數組格式 * @config {String} key 待存儲數據的key * @return {String} 本地存儲的數據,傳入為單個對象時,返回單個對象,獲取不到時返回null;傳入為數組時,返回為數組 */ get: function(obj) { //獲取某一個本地存儲 var _get_ = function(config) { //結果 var result = null; if (typeof config === "string") config = { key: config }; //key校驗 if (!_isValidKey(config.key)) { return result; } //支持本地存儲的瀏覽器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+ if (_isSupportLocalStorage) { 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); window.localStorage.removeItem(config.key + ".expires"); } } } else if (_isSupportUserData) { //IE7及以下版本,采用UserData方式 //這里不用單獨判斷其expires,因為UserData本身具有這個判斷 result = _getItem(config); if (result) { result = { value: result }; } } return result ? result.value : null; }; var rst = null; //判斷傳入的參數是否為數組 if (obj && obj.constructor === Array && obj instanceof Array) { rst = []; for (var i = 0, len = obj.length; i < len; i++) { rst.push(_get_(obj[i])); } } else if (obj) { rst = _get_(obj); } return rst; }, /** * 移除某一項本地存儲的數據 * <pre><code> * //刪除一個本地存儲項 * SummitLocalStorage.LocalStorage.remove({ * key : "username" * }); * //刪除多個本地存儲項目 * * SummitLocalStorage.LocalStorage.remove([{ * key : "username" * },{ * key : "password" * },{ * key : "sex" * }]); * </code></pre> * @param {String} obj 待移除的存儲數據相關配置,支持移除某一個本地存儲,也支持數組形式的批量移除 * @config {String} key 待移除數據的key * @return 無 */ remove: function(obj) { //移除某一項本地存儲的數據 var _remove_ = function(config) { //支持本地存儲的瀏覽器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+ if (_isSupportLocalStorage) { window.localStorage.removeItem(config.key); window.localStorage.removeItem(config.key + ".expires"); } else if (_isSupportUserData) { //IE7及以下版本,采用UserData方式 _removeItem(config); } }; //判斷傳入的參數是否為數組 if (obj && obj.constructor === Array && obj instanceof Array) { for (var i = 0, len = obj.length; i < len; i++) { _remove_(obj[i]); } } else if (obj) { _remove_(obj); } }, /** * 清除所有本地存儲的數據 * <pre><code> * SummitLocalStorage.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(); } }, //保存單個對象到本地 //save: function(EmployeeID, EmployeeName, EmployeeDescription,EmployeeAge) { // SummitLocalStorage.LocalStorage.set({ // /* key: EmployeeID + EmployeeName + EmployeeDescription+EmployeeAge,*/ // key:"wangbiaoTest3", // value: "{ ‘員工編號’: ‘" + EmployeeID + "’,‘員工姓名’: ‘" + EmployeeName + "’, ‘員工描述’:‘" + EmployeeDescription + "’, ‘員工年齡’:‘"+EmployeeAge+"’}", // expires: 3600 * 1000 /*單位:ms*/ // }); //}, save: function (result) { SummitLocalStorage.LocalStorage.set({ key: "summit", value: result, expires: 3600 * 1000 /*單位:ms*/ }); }, /** * 獲取所有的本地存儲數據對應的key * <pre><code> * var keys = SummitLocalStorage.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; } }; })();
接着先上控制器,准備數據:
[HttpPost] public ActionResult LocalStorage_Read() { var model = new List<UserModel> { new UserModel{Id=1,Name="summit",Age=20,Description="t5est",CreateOn=DateTime.Now}, new UserModel{Id=2,Name="alex",Age=20,Description="t5est",CreateOn=DateTime.Now}, new UserModel{Id=3,Name="glant",Age=20,Description="t5est",CreateOn=DateTime.Now} }; return Json(model); }
View中代碼如下:
<script src="~/Scripts/jquery-2.1.1.js"></script> <script src="~/Scripts/localstorage.js"></script> <script type="text/javascript"> $(function () { var Alldata = SummitLocalStorage.LocalStorage.get({ key: "summit" }); if (Alldata != null) {1 ReadStorageData(Alldata); } else { StorageData(); } function StorageData() { //把配置數據寫到LocalStorage中 $.ajax({ type: "POST", url: "/home/LocalStorage_Read", success: function (result) { var obj = JSON.stringify(result); SummitLocalStorage.LocalStorage.save(obj); Alldata = SummitLocalStorage.LocalStorage.get({ key: "summit" }); ReadStorageData(Alldata); } }); } function ReadStorageData(Alldata) { var data = JSON.parse(Alldata);//這里獲取到的值是一個數組,你可以按照你的想法去操作 var str = ""; for (var i = 0; i < data.length; i++) { str +="---"+ data[i].Id; } alert(str); } }); </script>
FireFox下效果如圖:
Google:
IE:
現在來解釋一下上面的代碼:
SummitLocalStorage.LocalStorage.get({ key: "summit" }); 獲取指定Key的值
SummitLocalStorage.LocalStorage.save(obj) ; save是js封裝的一個方法:用於保存一個對象,你也可以指定固定的參數傳遞.
在Asp.net MVC中使用LocalStorage還是挺方便的,LocalStorage容量為5M,是Cookies的N倍,有需要的朋友可以考慮一下。