一个在localStorage在HTML5的使用教程
本地存储的是什么
几天前,在旧项目中找到cookie操作是很奇怪的。经过协商,有必要缓存一些信息以避免在URL上传递参数,但没有考虑cookie会带来什么问题。
(1)cookie的大小限制在大约4K,不适合存储业务数据。
(2)每次都用HTTP发送cookie,浪费带宽。
我们是做移动的项目,这样真的很适合用在这里是本地存储技术,存储可以说优化的cookie,它可以用来存储数据在客户端的方便,它不会发送HTTP,但它也不是没有问题。
(1)对存储的大小限制为500万字左右,和各种浏览器不一致
在隐私模式存储不可读
(3)存储的基本读写文件,并且有一个比较卡的更多数据(Firefox将发送数据到内存时,认为这是可怕的)。
localStorage不能抓取爬虫,不要用它来完全代替URL
上述问题是可以避免的,所以我们应该把重点放在如何使用localStorage,和如何正确使用。
本地存储的使用
基本知识
localStorage存储对象分为两种:
的意思是:sessionstrage会话的会话含义。这里的会话指的是会话对象在用户浏览网站时,从进入网站到关闭网站的有效期。
存储:在客户端的硬件设备保存数据,不管它是什么,这意味着下一次的计算机打开,数据仍然存在。
两者的区别是暂时保存,长期保存。
这里有一个简单的代码来说明它的基本用法:
xml代码将内容复制到剪贴板。
身高:100px;>
sessionStorage
本地存储
保存数据
读取数据
var msg = document.getelementbyid('msg),
文本= document.getelementbyid(中的),
类型= document.getelementbyid();
函数保存(){
var str = text.value;
var t = type.value;
如果(T = = 'session){
sessionstorage.setitem('msg,STR);
{人}
localstorage.setitem('msg,STR);
}
}
函数加载(){
var t = type.value;
如果(T = = 'session){
msg.innerhtml = sessionstorage.getitem('msg);
{人}
msg.innerhtml = localstorage.getitem('msg);
}
}
真实的场景
在实际工作中,对存储的使用一般有以下要求:
(1)缓存一般信息,例如搜索页面的城市、城市、非实时位置信息。
2。缓存城市列表数据,这个数据通常更大。
三.每个缓存信息都需要可追溯性,例如,服务器通知城市数据更新。此时,我们必须在最新访问期间自动设置有效期。
每个信息都有过期的状态,服务器需要在过期的时间从服务器提取数据。
xml代码将内容复制到剪贴板。
定义(函数()){ }。
var存储= _。继承({
默认属性
特性:功能(){
/ /代理对象,默认为本地存储
this.sproxy = window.localstorage;
60 * 60 * 24 * 30 * 1000毫秒= 30天
this.defaultlifetime = 2592000000;
本地缓存来存储和映射的所有关键localStorage和到期日期
this.keycache = 'system_key_timeout_map;
当缓存容量满时,每次缓存删除的数量。
this.removenum = 5;
},
函数(){
如果(this.sproxy = null){
更throw'not重写属性;
}
},
初始化:功能(选择){
This.propertys();
This.assert();
},
*
新的本地存储
数据格式包括唯一键值、JSON字符串、到期日期和存款日期。
符号是格式化后的请求参数。当返回相同请求的不同参数时,它用于返回新数据。例如,该名单是北京的一个城市。切换到上海后,它将决定标记是否不同,并更新缓存的数据。标记相当于签名。
每个键的值只缓存一条信息。
* /
设置:函数(键,值,超时,符号){
无功_d =新的日期();
存款日期
VaR的有效期= _d.gettime();
最终保存的数据
var实体= null;
如果(!超时){
_d.settime(_d.gettime()+本。defaultlifetime);
超时= _d.gettime();
}
this.setkeycache(关键,超时);
实体= this.buildstorageobj(价值、有效期、超时、标志);
{试
this.sproxy.setitem(关键、JSON.stringify(实体));
返回true;
} catch(e){
当 / / localStorage是满的,这都是明确的。
如果(查询= = 'quotaexceedederror){
( / /本。更清晰。);
当 / /存储已满,选择最近的数据从到期日期删除。这也会有一些影响,但是感觉比所有的都好。如果缓存太多,这个过程是耗时的,小于100ms。
如果(!this.removelastcache())把这个数据存储太大;
this.set(键,值,超时,标志);
}
控制台console.log(E);
}
返回false;
},
删除已过期的缓存
removeoverduecache:函数(){
无功tmpobj =零,我,莱恩;
VAR现在=新的日期()GetTime();
退出/键
无功cachestr = this.sproxy.getitem(这个。keycache);
无功cachemap = { };
VaR NewMap = { };
如果(!cachestr){
返回;
}
cachemap = JSON.parse(cachestr);
为(i = 0,len = cachemap.length;我< len;i++){
tmpobj = cachemap {我};
如果(tmpobj.timeout <现在){
this.sproxy.removeitem(tmpobj。关键);
{人}
NewMap.push(tmpobj);
}
}
this.sproxy.setitem(this.keycache、JSON.stringify(部分));
},
removelastcache:函数(){
变量I,莱恩;
VaR Num = this.removenum | | 5;
退出/键
无功cachestr = this.sproxy.getitem(这个。keycache);
无功cachemap = { };
无功delmap = { };
这家商店太大了。
如果(!cachestr)返回false;
CacheMap.sort(功能(A,B){
返回a.timeout - b.timeout;
});
什么数据删除
delmap = cachemap.splice(0,努姆);
为(i = 0,len = delmap.length;我< len;i++){
This.sProxy.removeItem (delMap{i}.key);
}
this.sproxy.setitem(this.keycache,JSON.stringify(cachemap));
返回true;
},
setkeycache:功能(关键,超时){
如果超时(关键| | | |!!超时日期(GetTime)<<新(回));
无功我,莱恩,tmpobj;
获取当前已缓存的密钥字符串
无功oldstr = this.sproxy.getitem(这个。keycache);
无功oldmap = { };
当前键不存在
var标志= false;
var obj = { };
obj.key =关键;
obj.timeout =超时;
如果(oldstr){
oldmap = JSON.parse(oldstr);
如果(!_。ISArray(oldmap))oldmap = { };
}
为(i = 0,len = oldmap.length;我< len;i++){
tmpobj = oldmap {我};
如果(tmpobj.key = =键){
我oldmap { } = obj;
标志=真;
打破;
}
}
如果(!旗)oldmap.push(obj);
新的数组在缓存中
this.sproxy.setitem(this.keycache,JSON.stringify(oldmap));
},
buildstorageobj:功能(价值、有效期、超时、标志){
var obj = { {
价值:价值,
超时:超时,
签署:签字,
有效期:有效期
};
返回对象;
},
获取:函数(键,符号){
无功的结果,现在=新的日期()GetTime();
{试
结果:this.sproxy.getitem(关键);
如果(!结果)返回null;
结果= JSON.parse(结果);
数据过期
如果(result.timeout <现在)返回null;
验证签名
如果(符号){
如果(符号=结果,符号)
返回result.value;
返回null;
{人}
返回result.value;
}
} catch(e){
控制台console.log(E);
}
返回null;
},
获取签名
getsign:功能(关键){
var结果,符号= null;
{试
结果:this.sproxy.getitem(关键);
如果(结果){
结果= JSON.parse(结果);
结果result.sign符号=
}
} catch(e){
控制台console.log(E);
}
回签;
},
删除:函数(键){
返回this.sproxy.removeitem(关键);
},
清除:函数(){
This.sProxy.clear();
}
});
(storage.getinstance =功能){
如果(这个实例){
返回this.instance;
{人}
返回this.instance =新本();
}
};
返回存储;
});
此代码包含本地存储和处理的基本操作与上述问题,和真正的用途是被抽象。
xml代码将内容复制到剪贴板。
定义({ 'abstractstorage功能(abstractstorage){ },
代码_。继承({
默认属性
特性:功能(){
每个对象必须有一个存储键,不能重复。
this.key = null;
为s秒、m、d的默认数据生命周期
this.lifetime = '30m;
默认的返回数据
/ / this.defaultdata = null;
/ /代理对象,localStorage对象
this.sproxy =新abstractstorage();
},
SetOption:功能(可选){
_延长(这选项);
},
函数(){
如果(this.key = null){
throw'not覆盖关键属性;
}
如果(this.sproxy = null){
更throw'not重写属性;
}
},
初始化:功能(选择){
This.propertys();
this.setoption(选择);
This.assert();
},
_getlifetime:(功能){
var超时= 0;
var str = this.lifetime;
VaR(str.length str.charat单位= 1);
VaR Num = str.substring(0,str.length - 1);
var map { {
D:86400,
H:3600,
M:60,
S:1
};
如果(typeof单位= = 'String'){
unitunit = unit.touppercase();
}
超时数;
如果(单位)超时= map {单位};
返回值*超时* 1000;
},
数据缓存
设置:函数(值,符号){
获取/过期时间
var =新日期();
timeout.settime(timeout.gettime()+本。_getlifetime());
this.sproxy.set(this.key,价值,timeout.gettime(),标志);
},
单个属性集
setattr:功能(名称,价值,符号){
var obj的关键;
如果(_。采用(名字)){
对于(键中的名称){
如果(name.hasownproperty(关键))this.setattr(K,K的名字{ },值);
}
返回;
}
如果(!标志)标志= this.getsign();
获取当前对象
obj = this.get(标志)| | { };
如果(!Obj)返回;
obj {姓名} =价值;
this.set(obj,标志);
},
getsign:函数(){
返回this.sproxy.getsign(这个关键);
},
删除:函数(){
This.sProxy.remove(这个关键);
},
RemoveAttr:功能(attrname){
var = this.get(obj)| | { };
如果(obj { attrname }){
删除obj { attrname };
}
this.set(obj);
},
获取:函数(符号){
var result = { },空= true,一;
var obj = this.sproxy.get(this.key,标志);
变量类型=类型的对象;
var o = { 'String':真的,真的,'boolean若干':':true};
如果(O {型})返回的对象;
如果(_。ISArray(obj)){
对于(var i = 0,len = obj.length;我< len;i++){
结果{我} = obj {我};
}
} else if(_。采用(obj)){
结果=目标;
}
对于(结果中){
空= false;
打破;
}
返回!结果:空是空的;
},
GetAttr:功能(attrname,标签){
var obj = this.get(标签);
无功attrval = null;
如果(obj){
attrval = obj { attrname };
}
返回attrval;
}
});
(store.getinstance =功能){
如果(这个实例){
返回this.instance;
{人}
返回this.instance =新本();
}
};
返回商店;
});
当时我们实际使用的是使用存储类操作localStorage,和程序代码的简单测试:
存储完成后,它不会再去请求了,所以今天的代码基本上已经结束了。最后,Android混合系统中有一个后退按钮。一旦按下这个按钮,它会回到上一个页面,并将读取本地存储。一个简单的和不可靠的解决办法是加入webapp:
xml代码将内容复制到剪贴板。
window.onunload =函数(){ }; / /单页应用,不要问我为什么,我不知道
结论
本地存储是移动开发的关键技术点。我们需要有一个深刻的理解。具体的商业代码稍后会放在Git上,感兴趣的朋友可以理解。