总结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')