使用本地存储,web应用可以在用户浏览器中本地存储数据。
在HTML5之前,应用数据存储必须使用cookie,包括每个服务端的请求,本地存储更加安全,并且可以存储大量的数据到本地,不影响网站的性能。
和cookie不同的是,本地存储存储的数量很大(至少5MB)并且信息从来不会被传输到服务器端。
本地存储存储在域名和接口组成的网址下面,同一个网址下面可以相互获取信息。
浏览器支持
API | chrome | edge | IE | firefox | Safari | opera |
---|---|---|---|---|---|---|
Web Storage | 4.0 | 12.0 | 8.0 | 3.5 | 4.0 | 11.5 |
HTML本地存储对象
HTMNL本地存储在客户端对象提供了两个用于存储数据的对象:
- window.localStorage - 存储数据没有截止日期
- window.sessionStorage - 存储数据(当浏览器关闭的时候它也死掉了)
在使用本地存储之前,记得要用浏览器检测本地存储的兼容性:
if(typeof(Storage) !== "undefined") { // Code for localStorage/sessionStorage. } else { // Sorry! No Web Storage support.. }
下面会写polyfill,实际上就是利用cookie来仿本地存储,在最下面~
localStorage对象
localStorage对象是木有期限的,就算你关闭了浏览器它还是一直存在不离不弃,可以在明天,亦或下个星期,亦或明天使用
// Store localStorage.setItem("lastname", "Smith"); // Retrieve document.getElementById("result").innerHTML = localStorage.getItem("lastname");
例子解释:
- 创建了localStorage的键对值: name="lastname" 和value="Smith"
- 获取localStorage中lastname的值,并赋值给id为result的元素。
上面的例子也可以写成下面的样式:
// Store localStorage.lastname = "Smith"; // Retrieve document.getElementById("result").innerHTML = localStorage.lastname;
去除localsto中个“lastname”中的项目的语法如下:
localStorage.removeItem("lastname");
方法汇总
if(!localStorage.username){ name=prompt("What is your name?"); localStorage.username=name; } console.log(localStorage["username"]); localStorage.setItem("x",1);//以"x"的名字存储一个数值 localStorage.getItem("x");//获取数值 //枚举所有存储的名字/值对 for(var i=0;i<localStorage.length;i++){ //length表示了所有名字/值对的总数 var name=localStorage.key(i); //获取第i对名字,key在不知道键值的时候使用棒棒哒! var value=localStorage.getItem(name); //获取该对的值 } localStorage.removeItem("x"); //删除x项 localStorage.clear(); //全部删除
Note: 我们可以存储任何的数据类型,但是键对值总是被存储为string的形式(浏览器仅仅支持存储string类型的数据),所以,如果想存储和获取其他类型的数据,记得将数据进行编码和解码:
1 /* 2 * 和cookie比较的好处 3 * 1. 存储空间更大:IE8下每个独立的存储空间为10M,其他浏览器实现略有不同,但都比Cookie要大很多。 4 5 2. 存储内容不会发送到服务器:当设置了Cookie后,Cookie的内容会随着请求一并发送的服务器,这对于本地存储的数据是一种带宽浪费。而Web Storage中的数据则仅仅是存在本地,不会与服务器发生任何交互。 6 7 3. 更多丰富易用的接口:Web Storage提供了一套更为丰富的接口,使得数据操作更为简便。 8 9 4. 独立的存储空间:每个域(包括子域)有独立的存储空间,各个存储空间是完全独立的,因此不会造成数据混乱。 10 11 但是Cookie也是不可以或缺的:Cookie的作用是与服务器进行交互,作为HTTP规范的一部分而存在 ,而Web Storage仅仅是为了在本地“存储”数据而生 12 13 ① cookie大小限制在4k左右,不适合存业务数据 14 ② cookie每次随HTTP事务一起发送,浪费带宽 15 16 ① localstorage大小限制在500万字符左右,各个浏览器不一致 17 ② localstorage在隐私模式下不可读取 18 ③ localstorage本质是在读写文件,数据多的话会比较卡(firefox会一次性将数据导入内存,想想就觉得吓人啊) 19 ④ localstorage不能被爬虫爬取,不要用它完全取代URL传参 20 * */26 27 //当存储一个数字的时候,会把它自动转换成一个字符串 28 //但是,当获取该值的时候,不要忘记手动将其转换成数字类型 29 localStorage.x=10; 30 var x=parseInt(localStorage.x); 31 //存储一个日期类型数据时进行编码,获取时候进行解码 32 localStorage.lastRead=(new Date()).toUTCString(); 33 var lastRead=new Date(Date.parse(localStorage.lastRead)); 34 //使用JSON可以使得对基本数据类型编码工作变得非常方便 35 localStorage.data=JSON.stringify(data); 36 var data=JSON.parse(localStorage.data); 37
触发的事件
//storage事件,对键值的改变进行监听 setItem()中触发 if(window.addEventListener){ //通用浏览器 window.addEventListener("storage",handle_storage,false); }else if(window.attachEvent){ //IE浏览器 window.attachEvent("onstorage",handle_storage); } //storage 的event的属性有:key,newValue,oldValue,storageArea,url function handle_storage(e){ if(!e) e=window.event; //你的处理函数! }
sessionStorage对象
sessionStorage对象和localStorage对象基本一样,除了生命周期不一样:当特定的浏览器关闭的时候,sessionStorage中个data也死翘翘了。
在低浏览器中模拟本地对象:
if (!window.localStorage) { window.localStorage = { getItem: function (sKey) { if (!sKey || !this.hasOwnProperty(sKey)) { return null; } return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1")); }, key: function (nKeyId) { return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]); }, setItem: function (sKey, sValue) { if(!sKey) { return; } document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"; this.length = document.cookie.match(/\=/g).length; }, length: 0, removeItem: function (sKey) { if (!sKey || !this.hasOwnProperty(sKey)) { return; } document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; this.length--; }, hasOwnProperty: function (sKey) { return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie); } }; window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length; }
下面是一个复杂的方法 :
if (!window.localStorage) { window.localStorage = { getItem: function (sKey) { if (!sKey || !this.hasOwnProperty(sKey)) { return null; } return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1")); }, key: function (nKeyId) { return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]); }, setItem: function (sKey, sValue) { if(!sKey) { return; } document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"; this.length = document.cookie.match(/\=/g).length; }, length: 0, removeItem: function (sKey) { if (!sKey || !this.hasOwnProperty(sKey)) { return; } document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; this.length--; }, hasOwnProperty: function (sKey) { return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie); } }; window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length; }
上面实际上都是在操作cookie用来模拟本地存储,所以上面能够存储的最大数据时受到cookie的影响的。上面的代码中,使用localStorage.getItem()
, localStorage.setItem()
, 和 localStorage.removeItem()
来获取,设置和删除key是允许的,但是localStorage.yourKey方法来获取删除设置一个key是不被允许的。
当然,你也可以直接操作cookie。
如果将字符串 "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"
改变成 "; path=/"
(并且改变对象的名字), 那么将变成sessionStorage 的polyfill而不是lcoalStorage的polyfill。然而,这样的实现将会跨浏览器分享存储的数据(只有全部的windows中的所有浏览器都关闭的时候才会清楚),然而真正的sessionStorage中的数据只能在当前浏览器环境中共享数据的。