目前使用比較多的本地存儲方案有比如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倍,有需要的朋友可以考慮一下。
