头闻号

广州欧薇雅化妆品有限公司

熏香及熏香炉|减肥用品|瘦身化学品|丰胸化学品

首页 > 新闻中心 > 科技常识:HTML5中Localstorage的使用教程
科技常识:HTML5中Localstorage的使用教程
发布时间:2024-12-24 21:08:19        浏览次数:3        返回列表

今天小编跟大家讲解下有关HTML5中Localstorage的使用教程 ,相信小伙伴们对这个话题应该有所关注吧,小编也收集到了有关HTML5中Localstorage的使用教程 的相关资料,希望小伙伴们看了有所帮助。

什么是localstorage

  前几天在老项目中发现有对cookie的操作觉得很奇怪 咨询下来是要缓存一些信息 以避免在URL上面传递参数 但没有考虑过cookie会带来什么问题:

  ① cookie大小限制在4k左右 不适合存业务数据  ② cookie每次随HTTP事务一起发送 浪费带宽

  我们是做移动项目的 所以这里真实适合使用的技术是localstorage localstorage可以说是对cookie的优化 使用它可以方便在客户端存储数据 并且不会随着HTTP传输 但也不是没有问题:

  ① localstorage大小限制在500万字符左右 各个浏览器不一致  ② localstorage在隐私模式下不可读取  ③ localstorage本质是在读写文件 数据多的话会比较卡(firefox会一次性将数据导入内存 想想就觉得吓人啊)  ④ localstorage不能被爬虫爬取 不要用它完全取代URL传参

  瑕不掩瑜 以上问题皆可避免 所以我们的关注点应该放在如何使用localstorage上 并且是如何正确使用。localstorage的使用  基础知识

  localstorage存储对象分为两种:

  ① sessionStrage: session即会话的意思 在这里的session是指用户浏览某个网站时 从进入网站到关闭网站这个时间段 session对象的有效期就只有这么长。

  ② localStorage: 将数据保存在客户端硬件设备上 不管它是什么 意思就是下次打开计算机时候数据还在。

  两者区别就是一个作为临时保存 一个长期保存。

  这里来一段简单的代码说明其基本使用:

XML/HTML Code复制内容到剪贴板 <divid="msg"style="margin:10px0;border:1pxsolidblack;padding:10px;width:300px; height:100px;"> </div> <inputtype="text"id="text"/> <selectid="type"> <optionvalue="session">sessionStorage</option> <optionvalue="local">localStorage</option> </select> <buttononclick="save();"> 保存数据</button> <buttononclick="load();"> 读取数据</button> <scripttype="text/javascript"> varmsg=document.getElementById('msg'), text=document.getElementById('text'), type=document.getElementById('type'); functionsave(){ varstr=text.value; vart=type.value; if(t=='session'){ sessionStorage.setItem('msg',str); }else{ localStorage.setItem('msg',str); } } functionload(){ vart=type.value; if(t=='session'){ msg.innerHTML=sessionStorage.getItem('msg'); }else{ msg.innerHTML=localStorage.getItem('msg'); } } </script>

 真实场景

  实际工作中对localstorage的使用一般有以下需求:

  ① 缓存一般信息 如搜索页的出发城市 达到城市 非实时定位信息

  ② 缓存城市列表数据 这个数据往往比较大

  ③ 每条缓存信息需要可追踪 比如服务器通知城市数据更新 这个时候在最近一次访问的时候要自动设置过期

  ④ 每条信息具有过期日期状态 在过期外时间需要由服务器拉取数据

XML/HTML Code复制内容到剪贴板 define([],function(){ varStorage=_.inherit({ //默认属性 propertys:function(){ //代理对象 默认为localstorage this.sProxy=window.localStorage; //60*60*24*30*1000ms==30天 this.defaultLifeTime=2592000000; //本地缓存用以存放所有localstorage键值与过期日期的映射 this.keyCache='SYSTEM_KEY_TIMEOUT_MAP'; //当缓存容量已满 每次删除的缓存数 this.removeNum=5; }, assert:function(){ if(this.sProxy===null){ throw'notoverridesProxyproperty'; } }, initialize:function(opts){ this.propertys(); this.assert(); }, set:function(key,value,timeout,sign){ var_d=newDate(); //存入日期 varindate=_d.getTime(); //最终保存的数据 varentity=null; if(!timeout){ _d.setTime(_d.getTime()+this.defaultLifeTime); timeout=_d.getTime(); } // this.setKeyCache(key,timeout); entity=this.buildStorageObj(value,indate,timeout,sign); try{ this.sProxy.setItem(key,JSON.stringify(entity)); returntrue; }catch(e){ //localstorage写满时,全清掉 if(e.name=='QuotaExceededError'){ //this.sProxy.clear(); //localstorage写满时 选择离过期时间最近的数据删除 这样也会有些影响 但是感觉比全清除好些 如果缓存过多 此过程比较耗时 100ms以内 if(!this.removeLastCache())throw'本次数据存储量过大'; this.set(key,value,timeout,sign); } console&&console.log(e); } returnfalse; }, //删除过期缓存 removeOverdueCache:function(){ vartmpObj=null,i,len; varnow=newDate().getTime(); //取出键值对 varcacheStr=this.sProxy.getItem(this.keyCache); varcacheMap=[]; varnewMap=[]; if(!cacheStr){ return; } cacheMap=JSON.parse(cacheStr); for(i=0,len=cacheMap.length;i<len;i++){ tmpObj=cacheMap[i]; if(tmpObj.timeout<now){ this.sProxy.removeItem(tmpObj.key); }else{ newMap.push(tmpObj); } } this.sProxy.setItem(this.keyCache,JSON.stringify(newMap)); }, removeLastCache:function(){ vari,len; varnum=this.removeNum||5; //取出键值对 varcacheStr=this.sProxy.getItem(this.keyCache); varcacheMap=[]; vardelMap=[]; //说明本次存储过大 if(!cacheStr)returnfalse; cacheMap.sort(function(a,b){ returna.timeout-b.timeout; }); //删除了哪些数据 delMap=cacheMap.splice(0,num); for(i=0,len=delMap.length;i<len;i++){ this.sProxy.removeItem(delMap[i].key); } this.sProxy.setItem(this.keyCache,JSON.stringify(cacheMap)); returntrue; }, setKeyCache:function(key,timeout){ if(!key||!timeout||timeout<newDate().getTime())return; vari,len,tmpObj; //获取当前已经缓存的键值字符串 varoldstr=this.sProxy.getItem(this.keyCache); varoldMap=[]; //当前key是否已经存在 varflag=false; varobj={}; obj.key=key; obj.timeout=timeout; if(oldstr){ oldMap=JSON.parse(oldstr); if(!_.isArray(oldMap))oldMap=[]; } for(i=0,len=oldMap.length;i<len;i++){ tmpObj=oldMap[i]; if(tmpObj.key==key){ oldMap[i]=obj; flag=true; break; } } if(!flag)oldMap.push(obj); //最后将新数组放到缓存中 this.sProxy.setItem(this.keyCache,JSON.stringify(oldMap)); }, buildStorageObj:function(value,indate,timeout,sign){ varobj={ value:value, timeout:timeout, sign:sign, indate:indate }; returnobj; }, get:function(key,sign){ varresult,now=newDate().getTime(); try{ result=this.sProxy.getItem(key); if(!result)returnnull; result=JSON.parse(result); //数据过期 if(result.timeout<now)returnnull; //需要验证签名 if(sign){ if(sign===result.sign) returnresult.value; returnnull; }else{ returnresult.value; } }catch(e){ console&&console.log(e); } returnnull; }, //获取签名 getSign:function(key){ varresult,sign=null; try{ result=this.sProxy.getItem(key); if(result){ result=JSON.parse(result); sign=result&&result.sign } }catch(e){ console&&console.log(e); } returnsign; }, remove:function(key){ returnthis.sProxy.removeItem(key); }, clear:function(){ this.sProxy.clear(); } }); Storage.getInstance=function(){ if(this.instance){ returnthis.instance; }else{ returnthis.instance=newthis(); } }; returnStorage; });

这段代码包含了localstorage的基本操作 并且对以上问题做了处理 而真实的使用还要再抽象:

XML/HTML Code复制内容到剪贴板 define(['AbstractStorage'],function(AbstractStorage){ varStore=_.inherit({ //默认属性 propertys:function(){ //每个对象一定要具有存储键 并且不能重复 this.key=null; //默认一条数据的生命周期 S为秒 M为分 D为天 this.lifeTime='30M'; //默认返回数据 //this.defaultData=null; //代理对象 localstorage对象 this.sProxy=newAbstractStorage(); }, setOption:function(options){ _.extend(this,options); }, assert:function(){ if(this.key===null){ throw'notoverridekeyproperty'; } if(this.sProxy===null){ throw'notoverridesProxyproperty'; } }, initialize:function(opts){ this.propertys(); this.setOption(opts); this.assert(); }, _getLifeTime:function(){ vartimeout=0; varstr=this.lifeTime; varunit=str.charAt(str.length-1); varnum=str.substring(0,str.length-1); varMap={ D:86400, H:3600, M:60, S:1 }; if(typeofunit=='string'){ unitunit=unit.toUpperCase(); } timeout=num; if(unit)timeout=Map[unit]; //单位为毫秒 returnnum*timeout*1000; }, //缓存数据 set:function(value,sign){ //获取过期时间 vartimeout=newDate(); timeout.setTime(timeout.getTime()+this._getLifeTime()); this.sProxy.set(this.key,value,timeout.getTime(),sign); }, //设置单个属性 setAttr:function(name,value,sign){ varkey,obj; if(_.isObject(name)){ for(keyinname){ if(name.hasOwnProperty(key))this.setAttr(k,name[k],value); } return; } if(!sign)sign=this.getSign(); //获取当前对象 obj=this.get(sign)||{}; if(!obj)return; obj[name]=value; this.set(obj,sign); }, getSign:function(){ returnthis.sProxy.getSign(this.key); }, remove:function(){ this.sProxy.remove(this.key); }, removeAttr:function(attrName){ varobj=this.get()||{}; if(obj[attrName]){ deleteobj[attrName]; } this.set(obj); }, get:function(sign){ varresult=[],isEmpty=true,a; varobj=this.sProxy.get(this.key,sign); vartype=typeofobj; varo={'string':true,'number':true,'boolean':true}; if(o[type])returnobj; if(_.isArray(obj)){ for(vari=0,len=obj.length;i<len;i++){ result[i]=obj[i]; } }elseif(_.isObject(obj)){ result=obj; } for(ainresult){ isEmpty=false; break; } return!isEmpty?result:null; }, getAttr:function(attrName,tag){ varobj=this.get(tag); varattrVal=null; if(obj){ attrVal=obj[attrName]; } returnattrVal; } }); Store.getInstance=function(){ if(this.instance){ returnthis.instance; }else{ returnthis.instance=newthis(); } }; returnStore; });

  我们真实使用的时候是使用store这个类操作localstorage 代码结束简单测试:

 存储完成 以后都不会走请求 于是今天的代码基本结束 最后在android Hybrid中有一后退按钮 此按钮一旦按下会回到上一个页面 这个时候里面的localstorage可能会读取失效!一个简单不靠谱的解决方案是在webapp中加入:

XML/HTML Code复制内容到剪贴板 window.onunload=function(){};//适合单页应用 不要问我为什么 我也不知道

 结语

  localstorage是移动开发必不可少的技术点 需要深入了解 具体业务代码后续会放到git上 有兴趣的朋友可以去了解

来源:爱蒂网