一、本地存储
我们经常会使用Cookie来存储键值队数据。但是Cookie本身存在一定的局限性。
Cookie本身的局限性:
- 存储大小限制,仅4KB左右。
- 单个域名小的数量限制,50个左右。
- 污染请求头,浪费流量
所以对浏览器来说,使用 Web Storage 存储键值对比存储 Cookie 方式更好,而且容量更大。
Web Storage(本地存储)包含两种:localStorage 和 sessionStorage。
1.localStorage 和 sessionStorage
在浏览器的开发者工具下的Appliction中可以看到
就是这两个玩意。
两种存储方式的不同点:
1 .不同的存储时效:localStorage持久储存,除非主动删除数据,否则数据永远不会过期;sessionStorage会话结束(也就是网页关闭、浏览器关闭、或者说只标签页关闭)变会消失,而且存储的数据只能在同一个会话的页面才能访问。
2. 不同的存储容量:localStorage大小一般2-5M,sessionStorage存储大小不一样,一些浏览器不设限。
两种存储方式的相同点:
- 使用
...Storage.setItem('key','value')
设置内容。 - 使用
...storage.getItem('key')
方法获取内容。 - 使用
...Storage.removeItem('key')
方法清除内容。 - 使用
...Storage.clear()
方法清除所有内容。 - 使用
...Storage.length
属性获取长度。 - 使用
...Storage.key(index)
方法获取对应的下标的键值对的键名。
ps:localStorage和sessionStorage拥有相同的API,拥有不同的存储时效和容量
2.使用Storage的注意事项
由于各个浏览器对于Storage都有限制,我们使用的时候要注意一下几点。
2.1 存储容量超出限制
存储容量一旦超出限制,会抛出QuotaExceededError异常
**所以我们存储键值对时应该使用try{ ... }catch(e){ .... }
**来捕获异常。
2.2 存储类型的限制
Storage仅能存储字符串,所以在使用.setItem()设置值的时候
,浏览器会默认调用对象本身的toString()
方法,若没有,再调用浏览器的toString()
方法将任何值都转成字符串,再取数据的判断的时候注意类型。
//localStorage和sessionStorage的结果是一样的。
//**************************以下所有返回值都是String类型
localStorage.setItem('k1',false);
localStorage.getItem('k1'); // "false"
localStorage.setItem('k2',window.undefined);
localStorage.getItem('k2'); // "undefined"
localStorage.setItem('k3',null);
localStorage.getItem('k3'); // "null"
localStorage.setItem('k4',0);
localStorage.getItem('k4'); // "0"
localStorage.setItem('k5','');
localStorage.getItem('k5'); // ""
//空数组
localStorage.setItem('k6',[]);
localStorage.getItem('k6'); // ""
localStorage.setItem('k7',[1,2,3,4]);
localStorage.getItem('k7'); // "1,2,3,4"
//空对象
localStorage.setItem('k8',{
});
localStorage.getItem('k8'); // "[object Object]"
localStorage.setItem('k9',{
a:1});
localStorage.getItem('k9'); // "[object Object]"
localStorage.setItem('k10',{
toString:function(){
return 'tostringed'; }});
localStorage.getItem('k10'); // "tostringed"
localStorage.setItem('k11',{
toString: function(){
return 100;}});
localStorage.getItem('k11'); // "100"
从上面我们可以看出用Storage存储对象的话,会被统一转化成"[object Object]"
。
如果想使用Storage存储对象,方法如下
localStorage.setItem( 'k12',JSON.stringify({
data:123}) );
localStorage.getItem('k12'); // "{"data":123}"
//使用 JSON.parse可以将字符串转换成对象
JSON.parse( localStorage.getItem('k12'); ) // {data:123} | object类型
2.3 sessionStorage的失效机制
- 刷新页面不会失效
- 相同URL不同标签页不能共享sessionStorage
3.封装一个带有过期机制的localStorage
功能:
- 设置数据的存储时间(毫秒)
- 过期数据清理
- 自行维护存储容量
(function(){
var ls = window.localStorage;
function oops(){
//浏览器不支持localStorage警告
return console.warn('your browser is not supported localStorage API');
}
function getItem(key){
var data = ls.getItem(key);
data = JSON.parse(data) || {
}; //如果数据被情况,data会得到null,这里给他赋个空对象
if(data.time === 0){
//是持久化数据
return data.value;
}else if(Date.now() > data.time){
//数据过期
return '';
}else{
return typeof data.value !== 'undefined'? data.value : '';
}
}
function setItem(key,value,time){
if(typeof key === 'undefined')return;
var data = {
time: time? Date.now() + time : 0,
value : value
}
data = JSON.stringify(data);
try {
ls.setItem(key,data);
} catch(e){
ls.clear();
ls.setItem(key,data);
}
}
function removeItem(key){
ls.removeItem(key);
}
function clear(){
ls.clear();
}
window.myStorage = {
getItem: ls ? getItem : oops,
setItem: ls ? setItem : oops,
removeItem: ls ? removeItem : oops,
clear: ls ? clear : oops
}
})()
4.IndexedDB数据库
IndexedDB是HTML5规范里新出现的浏览器里内置的数据库。存储在IndexedDB里的数据是永久保存,不像cookies那样只是临时的。
- indexedDB数据库是一种事务型数据库
- 是NoSQL数据库
- 使用JS对象存储数据
- 创建的indexedDB数据库只有在同一个域名下才能共用
查看数据库
4.1 创建(打开)数据库
indexedDB.open(name,verson)
创建或连接数据库(name为数据库名称,verson为数据库版本,数据库创建时不指定verson会默认为1)- 连接数据库成功后,返回IDBOpenDBRequest对象
IDBOpenDBRequest
对象有3个重要回调函数- onerror:请求失败的回调函数
- onsuccess:请求成功的回调函数
- onup