Asp.net mvc 中使用LocalStorage

目前使用比较多的本地存储方案有比如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我进行了些修改,如下:

技术分享
  1 Namespace = new Object();
  2 // 全局对象仅仅存在register函数,参数为名称空间全路径,如"Grandsoft.GEA"
  3 Namespace.register = function(fullNS) {
  4     // 将命名空间切成N部分, 比如Grandsoft、GEA等
  5     var nsArray = fullNS.split(‘.‘);
  6     var sEval = "";
  7     var sNS = "";
  8     for (var i = 0; i < nsArray.length; i++) {
  9         if (i != 0) sNS += ".";
 10         sNS += nsArray[i];
 11         // 依次创建构造命名空间对象(假如不存在的话)的语句
 12         // 比如先创建Grandsoft,然后创建Grandsoft.GEA,依次下去
 13         sEval += "if (typeof(" + sNS + ") == ‘undefined‘) " + sNS + " = new Object();"
 14     }
 15     if (sEval != "") eval(sEval);
 16 }
 17 
 18 /**
 19  * 注册命名空间
 20  */
 21 Namespace.register(‘SummitLocalStorage‘);
 22 
 23 /**
 24  * @class SummitLocalStorage.LocalStorage
 25  * 跨浏览器的本地存储实现。高级浏览器使用localstorage,ie使用UserData。虽然说是本地存储,也请不要存储过大数据,最好不要大于64K.
 26  * 因为ie下UserData每页最大存储是64k。
 27  * @singleton
 28  * @author zhaoxianlie (xianliezhao@foxmail.com)
 29  */
 30 (function() {
 31     /**
 32      * 验证字符串是否合法的键名
 33      * @param {Object} key 待验证的key
 34      * @return {Boolean} true:合法,false:不合法
 35      * @private
 36      */
 37     function _isValidKey(key) {
 38         return (new RegExp("^[^\\x00-\\x20\\x7f\\(\\)<>@,;:\\\\\\\"\\[\\]\\?=\\{\\}\\/\\u0080-\\uffff]+\x24")).test(key);
 39     }
 40 
 41     //所有的key
 42     var _clearAllKey = "_baidu.ALL.KEY_";
 43 
 44     /**
 45      * 创建并获取这个input:hidden实例
 46      * @return {HTMLInputElement} input:hidden实例
 47      * @private
 48      */
 49     function _getInstance() {
 50         //把UserData绑定到input:hidden上
 51         var _input = null;
 52         //是的,不要惊讶,这里每次都会创建一个input:hidden并增加到DOM树种
 53         //目的是避免数据被重复写入,提早造成“磁盘空间写满”的Exception
 54         _input = document.createElement("input");
 55         _input.type = "hidden";
 56         _input.addBehavior("#default#userData");
 57         document.body.appendChild(_input);
 58         return _input;
 59     }
 60 
 61     /**
 62      * 将数据通过UserData的方式保存到本地,文件名为:文件名为:config.key[1].xml
 63      * @param {String} key 待存储数据的key,和config参数中的key是一样的
 64      * @param {Object} config 待存储数据相关配置
 65      * @cofnig {String} key 待存储数据的key
 66      * @config {String} value 待存储数据的内容
 67      * @config {String|Object} [expires] 数据的过期时间,可以是数字,单位是毫秒;也可以是日期对象,表示过期时间
 68      * @private
 69      */
 70     function __setItem(key, config) {
 71         try {
 72             var input = _getInstance();
 73             //创建一个Storage对象
 74             var storageInfo = config || {};
 75             //设置过期时间
 76             if (storageInfo.expires) {
 77                 var expires;
 78                 //如果设置项里的expires为数字,则表示数据的能存活的毫秒数
 79                 if (‘number‘ == typeof storageInfo.expires) {
 80                     expires = new Date();
 81                     expires.setTime(expires.getTime() + storageInfo.expires);
 82                 }
 83                 input.expires = expires.toUTCString();
 84             }
 85 
 86             //存储数据
 87             input.setAttribute(storageInfo.key, storageInfo.value);
 88             //存储到本地文件,文件名为:storageInfo.key[1].xml
 89             input.save(storageInfo.key);
 90         } catch (e) {}
 91     }
 92 
 93     /**
 94      * 将数据通过UserData的方式保存到本地,文件名为:文件名为:config.key[1].xml
 95      * @param {String} key 待存储数据的key,和config参数中的key是一样的
 96      * @param {Object} config 待存储数据相关配置
 97      * @cofnig {String} key 待存储数据的key
 98      * @config {String} value 待存储数据的内容
 99      * @config {String|Object} [expires] 数据的过期时间,可以是数字,单位是毫秒;也可以是日期对象,表示过期时间
100      * @private
101      */
102     function _setItem(key, config) {
103         //保存有效内容
104         __setItem(key, config);
105 
106         //下面的代码用来记录当前保存的key,便于以后clearAll
107         var result = _getItem({
108             key: _clearAllKey
109         });
110         if (result) {
111             result = {
112                 key: _clearAllKey,
113                 value: result
114             };
115         } else {
116             result = {
117                 key: _clearAllKey,
118                 value: ""
119             };
120         }
121 
122         if (!(new RegExp("(^|\\|)" + key + "(\\||$)", ‘g‘)).test(result.value)) {
123             result.value += "|" + key;
124             //保存键
125             __setItem(_clearAllKey, result);
126         }
127     }
128 
129     /**
130      * 提取本地存储的数据
131      * @param {String} config 待获取的存储数据相关配置
132      * @cofnig {String} key 待获取的数据的key
133      * @return {String} 本地存储的数据,获取不到时返回null
134      * @example
135      * SummitLocalStorage.LocalStorage.get({
136      *      key : "username"
137      * });
138      * @private
139      */
140     function _getItem(config) {
141         try {
142             var input = _getInstance();
143             //载入本地文件,文件名为:config.key[1].xml
144             input.load(config.key);
145             //取得数据
146             return input.getAttribute(config.key) || null;
147         } catch (e) {
148             return null;
149         }
150     }
151 
152     /**
153      * 移除某项存储数据
154      * @param {Object} config 配置参数
155      * @cofnig {String} key 待存储数据的key
156      * @private
157      */
158     function _removeItem(config) {
159         try {
160             var input = _getInstance();
161             //载入存储区块
162             input.load(config.key);
163             //移除配置项
164             input.removeAttribute(config.key);
165             //强制使其过期
166             var expires = new Date();
167             expires.setTime(expires.getTime() - 1);
168             input.expires = expires.toUTCString();
169             input.save(config.key);
170 
171             //从allkey中删除当前key            
172             //下面的代码用来记录当前保存的key,便于以后clearAll
173             var result = _getItem({
174                 key: _clearAllKey
175             });
176             if (result) {
177                 result = result.replace(new RegExp("(^|\\|)" + config.key + "(\\||$)", ‘g‘), ‘‘);
178                 result = {
179                     key: _clearAllKey,
180                     value: result
181                 };
182                 //保存键
183                 __setItem(_clearAllKey, result);
184             }
185 
186         } catch (e) {}
187     }
188 
189     //移除所有的本地数据
190     function _clearAll() {
191         result = _getItem({
192             key: _clearAllKey
193         });
194         if (result) {
195             var allKeys = result.split("|");
196             var count = allKeys.length;
197             for (var i = 0; i < count; i++) {
198                 if (!!allKeys[i]) {
199                     _removeItem({
200                         key: allKeys[i]
201                     });
202                 }
203             }
204         }
205     }
206 
207 
208     /**
209      * 获取所有的本地存储数据对应的key
210      * @return {Array} 所有的key
211      * @private
212      */
213     function _getAllKeys() {
214         var result = [];
215         var keys = _getItem({
216             key: _clearAllKey
217         });
218         if (keys) {
219             keys = keys.split(‘|‘);
220             for (var i = 0, len = keys.length; i < len; i++) {
221                 if (!!keys[i]) {
222                     result.push(keys[i]);
223                 }
224             }
225         }
226         return result;
227     }
228 
229     /**
230      * 判断当前浏览器是否支持本地存储:window.localStorage
231      * @return {Boolean} true:支持;false:不支持
232      * @remark 支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+
233      * @private
234          var _isSupportLocalStorage = ((‘localStorage‘ in window) && (window[‘localStorage‘] !== null)),
235         _isSupportUserData = !!jQuery.browser.ie;
236      */
237     var _isSupportLocalStorage = ((‘localStorage‘ in window) && (window[‘localStorage‘] !== null));
238 
239     SummitLocalStorage.LocalStorage = {
240         /**
241          * 如果支持本地存储,返回true;否则返回false
242          * @type Boolean
243          */
244         isAvailable: _isSupportLocalStorage || _isSupportUserData,
245 
246         /**
247          * 将数据进行本地存储(只能存储字符串信息)
248          * <pre><code>
249          * //保存单个对象
250          * SummitLocalStorage.LocalStorage.set({
251          *         key : "username",
252          *         value : "baiduie",
253          *         expires : 3600 * 1000
254          * });
255          * //保存对个对象
256          * SummitLocalStorage.LocalStorage.set([{
257          *         key : "username",
258          *         value : "baiduie",
259          *         expires : 3600 * 1000
260          * },{
261          *         key : "password",
262          *         value : "zxlie",
263          *         expires : 3600 * 1000
264          * }]);
265          * </code></pre>
266          * @param {Object} obj 待存储数据相关配置,可以是单个JSON对象,也可以是由多个JSON对象组成的数组
267          * <ul>
268          * <li><b>key</b> : String <div class="sub-desc">待存储数据的key,务必将key值起的复杂一些,如:baidu.username</div></li>
269          * <li><b>value</b> : String <div class="sub-desc">待存储数据的内容</div></li>
270          * <li><b>expires</b> : String/Object (Optional)<div class="sub-desc">数据的过期时间,可以是数字,单位是毫秒;也可以是日期对象,表示过期时间</div></li>
271          * </ul>
272          */
273         set: function(obj) {
274             //保存单个对象
275             var _set_ = function(config) {
276                 //key校验
277                 if (!_isValidKey(config.key)) {
278                     return;
279                 }
280 
281                 //待存储的数据
282                 var storageInfo = config || {};
283 
284                 //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+
285                 if (_isSupportLocalStorage) {
286                     window.localStorage.setItem(storageInfo.key, storageInfo.value);
287                     if (config.expires) {
288                         var expires;
289                         //如果设置项里的expires为数字,则表示数据的能存活的毫秒数
290                         if (‘number‘ == typeof storageInfo.expires) {
291                             expires = new Date();
292                             expires.setTime(expires.getTime() + storageInfo.expires);
293                         }
294 
295                         window.localStorage.setItem(storageInfo.key + ".expires", expires);
296                     }
297                 } else if (_isSupportUserData) { //IE7及以下版本,采用UserData方式
298                     _setItem(config.key, storageInfo);
299                 }
300             };
301 
302             //判断传入的参数是否为数组
303             if (obj && obj.constructor === Array && obj instanceof Array) {
304                 for (var i = 0, len = obj.length; i < len; i++) {
305                     _set_(obj[i]);
306                 }
307             } else if (obj) {
308                 _set_(obj);
309             }
310         },
311 
312         /**
313          * 提取本地存储的数据
314          * <pre><code>
315          * //获取某一个本地存储,返回值为:{key:"",value:"",expires:""},未取到值时返回值为:null
316          * var rst = SummitLocalStorage.LocalStorage.get({
317          *         key : "username"
318          * });
319          * //获取多个本地存储,返回值为:["","",""],未取到值时返回值为:[null,null,null]
320          * SummitLocalStorage.LocalStorage.get([{
321          *         key : "username"
322          * },{
323          *         key : "password"
324          * },{
325          *         key : "sex"
326          * }]);
327          * </code></pre>
328          * @param {String} obj 待获取的存储数据相关配置,支持单个对象传入,同样也支持多个对象封装的数组格式
329          * @config {String} key 待存储数据的key
330          * @return {String} 本地存储的数据,传入为单个对象时,返回单个对象,获取不到时返回null;传入为数组时,返回为数组
331          */
332         get: function(obj) {
333             //获取某一个本地存储
334             var _get_ = function(config) {
335                 //结果    
336                 var result = null;
337                 if (typeof config === "string") config = {
338                     key: config
339                 };
340                 //key校验
341                 if (!_isValidKey(config.key)) {
342                     return result;
343                 }
344 
345                 //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+
346                 if (_isSupportLocalStorage) {
347                     result = window.localStorage.getItem(config.key);
348                     //过期时间判断,如果过期了,则移除该项
349                     if (result) {
350                         var expires = window.localStorage.getItem(config.key + ".expires");
351                         result = {
352                             value: result,
353                             expires: expires ? new Date(expires) : null
354                         };
355                         if (result && result.expires && result.expires < new Date()) {
356                             result = null;
357                             window.localStorage.removeItem(config.key);
358                             window.localStorage.removeItem(config.key + ".expires");
359                         }
360                     }
361                 } else if (_isSupportUserData) { //IE7及以下版本,采用UserData方式
362                     //这里不用单独判断其expires,因为UserData本身具有这个判断
363                     result = _getItem(config);
364                     if (result) {
365                         result = {
366                             value: result
367                         };
368                     }
369                 }
370 
371                 return result ? result.value : null;
372             };
373 
374             var rst = null;
375             //判断传入的参数是否为数组
376             if (obj && obj.constructor === Array && obj instanceof Array) {
377                 rst = [];
378                 for (var i = 0, len = obj.length; i < len; i++) {
379                     rst.push(_get_(obj[i]));
380                 }
381             } else if (obj) {
382                 rst = _get_(obj);
383             }
384             return rst;
385         },
386 
387         /**
388          * 移除某一项本地存储的数据
389          * <pre><code>
390          * //删除一个本地存储项
391          * SummitLocalStorage.LocalStorage.remove({
392          *         key : "username"
393          * });
394          * //删除多个本地存储项目 *
395          * SummitLocalStorage.LocalStorage.remove([{
396          *         key : "username"
397          * },{
398          *         key : "password"
399          * },{
400          *         key : "sex"
401          * }]);
402          * </code></pre>
403          * @param {String} obj 待移除的存储数据相关配置,支持移除某一个本地存储,也支持数组形式的批量移除
404          * @config {String} key 待移除数据的key
405          * @return 无
406          */
407         remove: function(obj) {
408             //移除某一项本地存储的数据
409             var _remove_ = function(config) {
410                 //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+
411                 if (_isSupportLocalStorage) {
412                     window.localStorage.removeItem(config.key);
413                     window.localStorage.removeItem(config.key + ".expires");
414                 } else if (_isSupportUserData) { //IE7及以下版本,采用UserData方式
415                     _removeItem(config);
416                 }
417             };
418 
419             //判断传入的参数是否为数组
420             if (obj && obj.constructor === Array && obj instanceof Array) {
421                 for (var i = 0, len = obj.length; i < len; i++) {
422                     _remove_(obj[i]);
423                 }
424             } else if (obj) {
425                 _remove_(obj);
426             }
427         },
428 
429         /**
430          * 清除所有本地存储的数据
431          * <pre><code>
432          * SummitLocalStorage.LocalStorage.clearAll();
433          * </code></pre>
434          */
435         clearAll: function() {
436             //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+
437             if (_isSupportLocalStorage) {
438                 window.localStorage.clear();
439             } else if (_isSupportUserData) { //IE7及以下版本,采用UserData方式
440                 _clearAll();
441             }
442         },
443 
444         //保存单个对象到本地  
445         //save: function(EmployeeID, EmployeeName, EmployeeDescription,EmployeeAge) {
446         //    SummitLocalStorage.LocalStorage.set({
447         //       /* key: EmployeeID + EmployeeName + EmployeeDescription+EmployeeAge,*/
448         //       key:"wangbiaoTest3",
449         //        value: "{  ‘员工编号’: ‘" + EmployeeID + "’,‘员工姓名’: ‘" + EmployeeName + "’, ‘员工描述’:‘" + EmployeeDescription + "’, ‘员工年龄’:‘"+EmployeeAge+"’}",
450         //        expires: 3600 * 1000 /*单位:ms*/
451         //    });
452         //},
453         save: function (result) {
454             SummitLocalStorage.LocalStorage.set({
455                 key: "summit",
456                 value: result,
457                 expires: 3600 * 1000 /*单位:ms*/
458             });
459         },
460 
461         /**
462          * 获取所有的本地存储数据对应的key
463          * <pre><code>
464          * var keys = SummitLocalStorage.LocalStorage.getAllKeys();
465          * </code></pre>
466          * @return {Array} 所有的key
467          */
468         getAllKeys: function() {
469             var result = [];
470             //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+
471             if (_isSupportLocalStorage) {
472                 var key;
473                 for (var i = 0, len = window.localStorage.length; i < len; i++) {
474                     key = window.localStorage.key(i);
475                     if (!/.+\.expires$/.test(key)) {
476                         result.push(key);
477                     }
478                 }
479             } else if (_isSupportUserData) { //IE7及以下版本,采用UserData方式
480                 result = _getAllKeys();
481             }
482 
483             return result;
484         }
485     };
486 })();
代码有点长,点我点我查看~

接着先上控制器,准备数据:

 1 [HttpPost]
 2 public ActionResult LocalStorage_Read()
 3 {
 4      var model = new List<UserModel> { 
 5          new UserModel{Id=1,Name="summit",Age=20,Description="t5est",CreateOn=DateTime.Now},
 6          new UserModel{Id=2,Name="alex",Age=20,Description="t5est",CreateOn=DateTime.Now},
 7          new UserModel{Id=3,Name="glant",Age=20,Description="t5est",CreateOn=DateTime.Now}
 8     };
 9     return Json(model);
10 } 

 View中代码如下:

 1 <script src="~/Scripts/jquery-2.1.1.js"></script>
 2 <script src="~/Scripts/localstorage.js"></script>
 3 
 4 <script type="text/javascript">
 5         $(function () {
 6 
 7             var Alldata = SummitLocalStorage.LocalStorage.get({
 8                 key: "summit"
 9             });
10             if (Alldata != null) {
11                 ReadStorageData(Alldata);
12             }
13             else {
14                 StorageData();
15             }
16 
17             function StorageData() {
18                 //把配置数据写到LocalStorage中
19                 $.ajax({
20                     type: "POST",
21                     url: "/home/LocalStorage_Read",
22                     success: function (result) {
23                         var obj = JSON.stringify(result);
24                         SummitLocalStorage.LocalStorage.save(obj);
25                         Alldata = SummitLocalStorage.LocalStorage.get({ key: "summit" });
26                         ReadStorageData(Alldata);
27                     }
28                 });
29             }
30 
31             function ReadStorageData(Alldata) {
32                 var data = JSON.parse(Alldata);//这里获取到的值是一个数组,你可以按照你的想法去操作
33                 var str = "";
34                 for (var i = 0; i < data.length; i++) {
35                     str +="---"+ data[i].Id;
36                 }
37                 alert(str);
38             }
39         });
40 </script>

FireFox下效果如图:

技术分享

Google:

技术分享

IE:

技术分享

现在来解释一下上面的代码:

SummitLocalStorage.LocalStorage.get({ key: "summit" }); 获取指定Key的值

SummitLocalStorage.LocalStorage.save(obj) ; save是js封装的一个方法:用于保存一个对象,你也可以指定固定的参数传递.

在Asp.net MVC中使用LocalStorage还是挺方便的,LocalStorage容量为5M,是Cookies的N倍,有需要的朋友可以考虑一下。

 

文章来自:http://www.cnblogs.com/summit7ca/p/4462197.html
© 2021 jiaocheng.bubufx.com  联系我们
ICP备案:鲁ICP备09046678号-3