总结JavaScript三种数据存储方式之间的区别
sessionStorage、localStorage和cookie之间的共同点:
都是保存在浏览器端,且同源的。
sessionStorage、localStorage和cookie之间的区别:
cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。
存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。
WebStorage支持事件通知机制,可以将数据更新的通知发送给监听者。
WebStorage的api接口使用更方便。
封装的localStorage的方法,可以控制存储数据的条数,以及时间
define(function(require){ var$=require('jquery'); varCache={}; functionsupport(){ var_t=!(typeofwindow.localStorage==='undefined'); return_t; } $.extend(Cache,{ config:{ size:5, //lifeTime:86400//一天的秒数 lifeTime:1*60 }, localStorage:window.localStorage, memQueue:(function(){ if(support()){ varjsonStr=window.localStorage.getItem('LRUConfig'); returnjsonStr?JSON.parse(jsonStr):{ keys:{}, objs:[] }; }else{ return{}; } })(), get:function(appid,url){ if(true==support()){ varkey=appid+':'+url; //开始做LRU算法。 this.LRU(key); //LRU算法结束。 varisFresh=true; varnowTime=(newDate()).getTime()/1000; if(keyinthis.memQueue.keys){ varcacheTime=this.memQueue.keys[key].life/1000; //如果过期时间超过配置的lifeTime, //则清除掉当前缓存 if(nowTime-cacheTime>=this.config.lifeTime){ deletethis.memQueue.keys[key]; for(vari=0,len=this.memQueue.objs.length;i<len;i++){ var_o=this.memQueue.objs[i]; if(_o.key==key){ this.memQueue.objs.splice(i,1); break; } } isFresh=false; } } //如果isFresh为假,就是已过期,则返回null,否则从localStorage中取 return(false==isFresh)?null:this.localStorage[key]; } }, set:function(appid,url,value){ if(true==support()){ varkey=appid+':'+url; varlruKey=this.getLRU(); //淘汰最近最少使用的这个。 //另外起一个方法读取最符合淘汰的这个 //前提是当前这个key,不在localStorage里面。 if(lruKey){ this.localStorage.removeItem(lruKey); } //开始设置一下这个值 //为了兼容性,用以下方法设置 if(typeofthis.memQueue.objs!='undefined'&& this.memQueue.objs.length<=this.config.size){ this.localStorage.removeItem(key); }else{ while(this.memQueue.objs.length>=this.config.size){ varlruKey=this.getLRU(); //淘汰最近最少使用的这个。 //另外起一个方法读取最符合淘汰的这个 if(lruKey){ this.localStorage.removeItem(lruKey); deletethis.memQueue.keys[lruKey]; for(vari=0;i<this.memQueue.objs.length;i++){ var_o=this.memQueue.objs[i]; if(_o.key==lruKey){ this.memQueue.objs.splice(i,1); break; } } } } } this.localStorage[key]=value; //当前的key,也必须lru一下 this.LRU(key); //lru结束 this.localStorage.setItem('LRUConfig',JSON.stringify(this.memQueue)); } }, /* *近期最少使用算法 */ LRU:function(key){ varmemQueue=this.memQueue; if(typeofmemQueue.objs!='undefined'){ var_o=memQueue.objs; //开始计算那个要淘汰的key, //就是那个times最大的,如果times最大的有几个 //则返回那个time最小的 varisIn=false; for(vari=0,len=_o.length;i<len;i++){ _o[i].times=(key==_o[i].key)?0:_o[i].times+1; _o[i].time=(key==_o[i].key)?(newDate()).getTime():_o[i].time; if(key==_o[i].key&&false==isIn){ isIn=true; } } //如果 if(false==isIn){ var_to={ 'key':key, 'times':0, 'time':(newDate()).getTime(), 'life':(newDate()).getTime() }; this.memQueue.keys[key]=_to; this.memQueue.objs.push(_to); } _o.sort(function(f,s){ //按times降序排列。 if(f.times<s.times){ return1; }elseif(f.times>s.times){ return-1; }else{ //开始比较time //按time,时间升序排列 if(f.time<s.time){ return-1; }else{ return1; } } }); }else{ this.memQueue.objs=[]; this.memQueue.keys={}; var_to={ 'key':key, 'times':0, 'time':(newDate()).getTime(), 'life':(newDate()).getTime() }; this.memQueue.keys[key]=_to; this.memQueue.objs.push(_to); returnnull; } }, /* *读取需要淘汰的一项 */ getLRU:function(){ var_o=this.memQueue.objs; if(_o){ return(_o.length>=this.config.size)?_o.shift().key:null; } returnnull; } }); return{ 'cache':Cache }; });
使用方法
varcache=require('cache'); //set值 cache.Cache.set('ip','你自己的一个url',value); //get值 cache.Cache.get('ip')