UDN-企业互联网技术人气社区

板块导航

浏览  : 1563
回复  : 4

[HTML5] html5中本地存储替代cookie:qext.LocalStorage例子

[复制链接]
友美的小妹的头像 楼主
发表于 2015-7-24 11:29:37 | 显示全部楼层 |阅读模式
本帖最后由 友美的小妹 于 2015-8-10 20:24 编辑

  背景

  先看看各种本地存储的变革:

  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实例:


  1. /**
  2. * 创建并获取这个input:hidden实例
  3. * @return {HTMLInputElement} input:hidden实例
  4. * @private
  5. */
  6. function _getInstance(){
  7.     //把UserData绑定到input:hidden上
  8.     var _input = null;
  9.     //是的,不要惊讶,这里每次都会创建一个input:hidden并增加到DOM树种
  10.     //目的是避免数据被重复写入,提早造成“磁盘空间写满”的Exception
  11.     _input = document.createElement("input");
  12.     _input.type = "hidden";
  13.     _input.addBehavior("#default#userData");
  14.     document.body.appendChild(_input);
  15.     return _input;
  16. }
复制代码

  本地数据存储:

  1. /**
  2. * 将数据通过UserData的方式保存到本地,文件名为:文件名为:config.key[1].xml
  3. * @param {String} key 待存储数据的key,和config参数中的key是一样的
  4. * @param {Object} config 待存储数据相关配置
  5. * @cofnig {String} key 待存储数据的key
  6. * @config {String} value 待存储数据的内容
  7. * @config {String|Object} [expires] 数据的过期时间,可以是数字,单位是毫秒;也可以是日期对象,表示过期时间
  8. * @private
  9. */
  10. function __setItem(key,config){
  11.     try {
  12.         var input = _getInstance();
  13.         //创建一个Storage对象
  14.         var storageInfo = config || {};
  15.         //设置过期时间
  16.         if(storageInfo.expires) {
  17.             var expires;
  18.             //如果设置项里的expires为数字,则表示数据的能存活的毫秒数
  19.             if ('number' == typeof storageInfo.expires) {
  20.                 expires = new Date();
  21.                 expires.setTime(expires.getTime() + storageInfo.expires);
  22.             }
  23.             input.expires = expires.toUTCString();
  24.         }
  25.                  
  26.         //存储数据
  27.         input.setAttribute(storageInfo.key,storageInfo.value);
  28.         //存储到本地文件,文件名为:storageInfo.key[1].xml
  29.         input.save(storageInfo.key);
  30.     } catch (e) {
  31.     }
  32. }
复制代码


  再看userData本地数据的读取:


  1. /**
  2. * 提取本地存储的数据
  3. * @param {String} config 待获取的存储数据相关配置
  4. * @cofnig {String} key 待获取的数据的key
  5. * @return {String} 本地存储的数据,获取不到时返回null
  6. * @example
  7. * qext.LocalStorage.get({
  8. *      key : "username"
  9. * });
  10. * @private
  11. */
  12. function _getItem(config){
  13.     try {
  14.         var input = _getInstance();
  15.         //载入本地文件,文件名为:config.key[1].xml
  16.         input.load(config.key);
  17.         //取得数据
  18.         return input.getAttribute(config.key) || null;
  19.     } catch (e) {
  20.         return null;           
  21.     }
  22. }
  23. 模拟remove操作:
  24. /**
  25. * 移除某项存储数据
  26. * @param {Object} config 配置参数
  27. * @cofnig {String} key 待存储数据的key
  28. * @private
  29. */
  30. function _removeItem(config){
  31.     try {
  32.         var input = _getInstance();
  33.         //载入存储区块
  34.         input.load(config.key);
  35.         //移除配置项
  36.         input.removeAttribute(config.key);
  37.         //强制使其过期
  38.         var expires = new Date();
  39.         expires.setTime(expires.getTime() - 1);
  40.         input.expires = expires.toUTCString();
  41.         input.save(config.key);
  42.                
  43.         //从allkey中删除当前key         
  44.         //下面的代码用来记录当前保存的key,便于以后clearAll
  45.         var result = _getItem({key : _clearAllKey});
  46.         if(result) {
  47.             result = result.replace(new RegExp("(^||)" + config.key + "(||$)",'g'),'');
  48.             result = {
  49.                 key : _clearAllKey,
  50.                 value : result
  51.             };
  52.             //保存键
  53.             __setItem(_clearAllKey,result);
  54.         }
  55.                
  56.     } catch (e) {
  57.     }
  58. }
复制代码

  2、再看HTML5-LocalStorage中expires的模拟:

  1. 在进行数据存储的时候,单独多存一个字段:key + ".expires",如果传入的expires为数字类型,单位则是毫秒(ms)
  2. window.localStorage.setItem(storageInfo.key,storageInfo.value);
  3. // 如果需要指定生命周期
  4. if(config.expires) {
  5.     var expires;
  6.     //如果设置项里的expires为数字,则表示数据的能存活的毫秒数
  7.     if ('number' == typeof storageInfo.expires) {
  8.         expires = new Date();
  9.         expires.setTime(expires.getTime() + storageInfo.expires);
  10.     }
  11.   
  12.     window.localStorage.setItem(storageInfo.key + ".expires",expires);
  13. }
  14. 在数据读取的时候,通用读取这个字段,判断时间是否超出了生命周期
  15. result = window.localStorage.getItem(config.key);
  16. //过期时间判断,如果过期了,则移除该项
  17. if(result) {
  18.     var expires = window.localStorage.getItem(config.key + ".expires");
  19.     result = {
  20.         value : result,
  21.         expires : expires ? new Date(expires) : null
  22.     };
  23.     if(result && result.expires && result.expires < new Date()) {
  24.         result = null;
  25.         window.localStorage.removeItem(config.key);
  26.     }
  27. }
复制代码

  3、提取所有key

  1. /**
  2. * 获取所有的本地存储数据对应的key
  3. * <pre><code>
  4. * var keys = qext.LocalStorage.getAllKeys();
  5. * </code></pre>
  6. * @return {Array} 所有的key
  7. */
  8. getAllKeys : function(){
  9.     var result = [];
  10.     //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+
  11.     if(_isSupportLocalStorage) {
  12.         var key;
  13.         for(var i = 0,len = window.localStorage.length;i < len;i++){
  14.             key = window.localStorage.key(i);
  15.             if(!/.+.expires$/.test(key)) {
  16.                 result.push(key);
  17.             }
  18.         }
  19.     } else if(_isSupportUserData) { //IE7及以下版本,采用UserData方式
  20.         result = _getAllKeys();
  21.     }
  22.          
  23.     return result;
  24. }
复制代码

  4、清除所有本地存储的数据

  1. /**
  2. * 清除所有本地存储的数据
  3. * <pre><code>
  4. * qext.LocalStorage.clearAll();
  5. * </code></pre>
  6. */
  7. clearAll : function(){
  8.     //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+
  9.     if(_isSupportLocalStorage) {
  10.         window.localStorage.clear();
  11.     } else if(_isSupportUserData) { //IE7及以下版本,采用UserData方式
  12.         _clearAll();
  13.     }
  14. }
复制代码

  关于使用方法

  1、数据存储:qext.LocalStorage.set

  1. // 保存单个对象到本地
  2. qext.LocalStorage.set({
  3.    key : "username",
  4.    value : "baiduie",
  5.    expires : 3600 * 1000  /*单位:ms*/
  6. });
  7.       
  8. // 保存多个对象
  9. qext.LocalStorage.set([{
  10.    key : "username",
  11.    value : "baiduie",
  12.    expires : 3600 * 1000  /*单位:ms*/
  13. },{
  14.    key : "password",
  15.    value : "zxlie",
  16.    expires : 3600 * 1000  /*单位:ms*/
  17. }]);
  18. 2、数据提取:qext.LocalStorage.get
  19. //获取某一个本地存储,返回值为:{key:"",value:"",expires:""},未取到值时返回值为:null
  20. var rst = qext.LocalStorage.get({
  21.     key : "username"
  22. });
  23.      
  24. //获取多个本地存储,返回值为:["","",""],未取到值时返回值为:[null,null,null]
  25. qext.LocalStorage.get([{
  26.     key : "username"
  27. },{
  28.     key : "password"
  29. },{
  30.     key : "sex"
  31. }]);
  32. 3、数据删除:qext.LocalStorage.remove
  33. //删除一个本地存储项
  34. qext.LocalStorage.remove({
  35.     key : "username"
  36. });
  37.      
  38. //删除多个本地存储项目
  39. qext.LocalStorage.remove([{
  40.     key : "username"
  41. },{
  42.     key : "password"
  43. },{
  44.     key : "sex"
  45. }]);
  46. 4、清空所有数据:qext.LocalStorage.clearAll
  47. // 清空所有本地存储的数据
  48. qext.LocalStorage.clearAll();
  49. 5、获取所有本地存储的key:qext.LocalStorage.getAllKes
  50. // 获取所有本地存储的key
  51. var keys = qext.LocalStorage.getAllKeys();
复制代码





相关帖子

发表于 2015-8-10 20:44:44 | 显示全部楼层
兼容性方面,HTML5有优势
使用道具 举报

回复

发表于 2015-8-14 19:00:32 | 显示全部楼层
路过 帮顶 嘿嘿
使用道具 举报

回复

发表于 2015-8-15 07:55:42 | 显示全部楼层
无论是不是沙发都得回复下
使用道具 举报

回复

发表于 2015-9-9 16:22:26 | 显示全部楼层
LocalStorage 也是存在文件里吗??
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部