有关localStorage和sessionStorage的特性。
localStorage本身带有方法有
添加键值对:localStorage.setItem(key,value),如果key存在时,更新value。
获取键值:localStorage.getItem(key),如果key不存在返回null。
删除键值对:localStorage.removeItem(key)。key对应的数据将会全部删除。
清除所有键值对:localStorage.clear()。如果调用clear()方法,清空localStorage中所有信息,那么key、oldValue和newValue都会被设置为null。
获取localStorage的属性名称(键名称):localStorage.key(index)。
还有一个和普通对象不一样的属性length:
获取localStorage中保存的键值对的数量:localStorage.length。
下面这个例子用来获取localStorage的键值对
for(var i=0;i<localStorage.length;i++){
console.log(localStorage.key(i)+ " : " + localStorage.getItem(localStorage.key(i)));
}
1、存储格式
localStorage对象的键和值只能是字符串,假设我们要保存一个对象到localStorage中,可以使用拼接的方式。当然也可以借助JSON类,将对象转换成字符串保存,然后在取出来的时候将json字符串转换成真正可用的json对象格式
存储JSON格式数据
JSON.stringify(data) 将一个对象转换成JSON格式的数据串,返回转换后的串
JSON.parse(data) 将数据解析成对象,返回解析后的对象
(虽然规范中可以存储其他原生类型的对象,但是目前为止没有浏览器对其进行实现)。
2、生命周期
在数据存储的时效性上,localStorage并不会像cookie那样可以设置数据存活的时限。也就是说,只要用户不主动删除,localStorage存储的数据将会永久存在。
sessionStorage生命周期为当前窗口或标签页,一旦窗口或标签页被永久关闭了,那么所有通过sessionStorage存储的数据也就被清空了。
3、存储位置
当然,对于localStorage数据的存储,是存在于本地的文件系统中的,例如,对于chrome来说,localStorage数据的存储位置是在:C:\Users\{userName}\AppData\Local\Google\Chrome\User Data\Default\Local Storage中。对于其他4大浏览器,大家可以自行查找进行查看。
4、数据共享
不同浏览器无法共享localStorage或sessionStorage中的信息。相同浏览器的不同页面间可以共享相同的localStorage(页面属于相同域名和端口),但是不同页面或标签页间无法共享sessionStorage的信息。这里需要注意的是,页面及标签页仅指*窗口,如果一个标签页包含多个iframe标签且他们属于同源页面,那么他们之间是可以共享sessionStorage的。
5、兼容性
可以看到,除IE外的其他浏览器很早的版本都支持了,对于IE低版本系列的浏览器,我们需要一个兼容方案来处理。
微软在IE5.0以后,自定义了一种持久化用户数据的概念userData,这种存储方式只有IE浏览器自己支持。来看看其如何操作——
(function(win) {
// 对于IE,且不支持localStorage的浏览器
// 即针对IE6/7
if ( typeof win.attachEvent != "undefined" && typeof win.localStorage == "undefined") {
var localFileName = "_simulateLocalStorage",
expires = 365,
formField = null;
// 设置有效期为365天
var expire = new Date();
expire.setDate(expires + expire.getDate());
formField = document.createElement("input");
formField.type = "hidden";
formField.addBehavior('#default#userData');
document.body.appendChild(formField);
var storage = {
setItem : function(key, value) {
formField.load(localFileName);
formField.setAttribute(key, value);
formField.save(localFileName);
},
getItem : function(key) {
formField.load(localFileName);
return formField.getAttribute(key);
},
removeItem : function(key) {
formField.load(localFileName);
formField.removeAttribute(key);
formField.save(localFileName);
},
clear : function() {
formField.load(localFileName);
var d = new Date();
d.setDate(d.getDate() - 1);
formField.expires = d.toUTCString();
formField.save(localFileName);
}
};
win["localStorage"] = storage;
}
})(window);
这里仅仅是对IE兼容性的简单包装,下面的链接给出非常完善的针对localStorage兼容性的解决方案。
https://github.com/machao/localStorage
6、存储大小
对于HTML5的localStorage而言,其大小支持为5M(当然,各浏览器的大小差异还是有的)。对于IE的userData,用户数据的每个域最大为64KB。
7、应用场景
建议不要使用localStorage方式存储敏感信息,哪怕这些信息进行过加密。另外,对身份验证数据使用localStorage进行存储还不太成熟。我们知道,通常可以通过xss漏洞来获取到Cookie,然后用这个Cookie进行身份验证登录,但是浏览器可以通过HttpOnly来保护Cookie不被XSS攻击获取到。而localStorage存储没有对XSS攻击有任何防御机制,一旦出现XSS漏洞,那么存储在localStorage里的数据就极易被获取到。
storage事件:当存储的storage数据发生变化时都会触发它,但是它不同于click类的事件会冒泡和能取消,storage改变的时候,触发这个事件会调用所有同域下其他窗口的storage事件,不过它本身触发storage即当前窗口是不会触发这个事件的(当然ie这个特例除外,它包含自己本事也会触发storage事件)。
在使用 Storage 进行存取操作的同时,如果需要对存取操作进行监听,可以使用 HTML5 Web Storage api 内置的事件监听器对数据进行监控。只要 Storage 存储的数据有任何变动,Storage 监听器都能捕获。
interface Storage : Event{
readonly attribute DOMString key;
readonly attribute DOMString? oldValue;
readonly attribute DOMString? newValue;
readonly attribute DOMString url;
readonly attribute Storage? storageArea;
void initStorageEvent(in DOMString typeArg,
in boolean canBubbleArg,
in boolean cancelableArg,
in DOMString keyArg,
in DOMString oldValueArg,
in DOMString newValueArg,
in DOMString urlArg,
in Storage storageAreaArg);
};
不难看出其中包含以下属性:
- key 属性表示存储中的键名
- oldValue 属性表示数据更新前的键值,newValue 属性表示数据更新后的键值。如果数据为新添加的,则 oldValue 属性值为 null。如果数据通过 removeItem 被删除,则 newValue 属性值为 null 。如果 Storage 调用的是 clear 方法,则事件中的 key 、oldValue 、newValue 都是为 null
- url 属性记录 Storage 时间发生时的源地址
- StorageArea 属性指向事件监听对应的 Storage 对象
Storage 事件可以使用 W3C 标准的注册事件方法 addEventListenter 进行注册监听。例如:
window.addEventlistener("storage",showStorageEvent,false);
function showStorageEvent(e){
console.log(e)
}
举例:
页面a下,有个input框用来存储store,它自身绑定了storage事件,这个时候写入新的数据点击保存,这时新的sotre数据保存了,但是页面a的storage事件没触发,
而页面b下,绑定的storage事件则触发了。(ps:前提页面a和b在同域下,并都是打开状态不同窗口);
页面a代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<input type="text" placeholder="input date to save">
<button>save</button>
<script>
(function(D){
var val = D.getElementsByTagName("input")[0],
btn = D.getElementsByTagName("button")[0];
btn.onclick = function(){
var value = val.value;
if(!value) return;
localStorage.setItem("key", val.value);
};
window.addEventListener("storage", function(e){
console.log(e);
});
})(document);
</script>
</body>
</html>
页面b代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
window.addEventListener("storage", function(e){
console.log(e);
document.write("oldValue: "+ e.oldValue + " newValue:" + e.newValue)
});
</script>
</body>
</html>
看到这里是不是很疑惑那storage事件到底有什么用,多窗口间多通信用到它就是最好选择了,比如某块公用内容区域基础数据部分都是从store中提取的,这个区域中大多数页面中都有,当用户打开多个页面时,在其中一个页面做了数据修改,那其他页面同步更新是不是很方便(当前页面就要用其他方式处理了),当然用于窗口间通信它作用不仅仅如此,更多的大家可以利用它特性去发挥。
在上面的demo页面b中storage的events对象的属性常用的如下:
oldValue:更新前的值。如果该键为新增加,则这个属性为null。
newValue:更新后的值。如果该键被删除,则这个属性为null。
url:原始触发storage事件的那个网页的网址。
key:存储store的key名;
参考:
1>http://www.cnblogs.com/jinguangguo/p/4083919.html
2> http://blog.csdn.net/nx8823520/article/details/30478859