23-存储会话:cookie、WebStorage和indxDB
存储会话的两种途径:Cookie和Web Storage。
存储会话是什么意思呢?毕竟机器它们又不能真的讲话。所以,我就把存储会话理解为存储用户的信息,比如说用户名和密码,用户一旦输入过后,浏览器就能自己记住这些信息,不用再去记录了。
一、将数据存储在客户端上——cookie
该标准要求,服务器对请求发送Set-Cookie HTTP头,作为响应的一部分。
Set-Cookie头包括name、value。名称和值在传送过程中是以URL编码的。
1、限制
2、cookie的构成
名称:不区分大小写,经过url编码。
值:字符串,经过url编码的。
3、JS中的cookie
一个接口和一个方法,document.cookie和decodeURIComponent()。
该方法是解码用的。
最好每次设置cookie时都要使用encodeURIComponent()编码。
document.cookie=encodeURIComponent("name")+"="+encodeURIComponent("Alice");
document.cookie=encodeURIComponent("name")+"="+encodeURIComponent("Tony")+";domain=.wrox.com";
要给创建的cookie指定额外信息,就要将参数追加到这个字符串上。以分号加一个空格“; ”分割。
JS对cookie的获取是通过document.cookie这个接口来取得的。写一个对象,里面包含各种方法可以简化cookie的读取、写入和删除。
var CookieUtil={ //获取cookie get:function(name){ //得到的是经过编码的值 var cookieName=encodeURIComponent(name)+"="; var cookieStart=document.cookie.indexOf(cookieName); var cookieValue=null; if (cookieStart>-1){ //cookie存在 var cookieEnd=document.cookie.indexOf(";",cookieStart); if(cookieEnd==-1){ cookieEnd=document.cookie.length; } cookieValue=decodeURIComponent(document.cookie.substring(cookieStart+cookieName.length,cookieEnd)) } return cookieValue; }, //创建cookie set:function(name,value,expires,path,domain,secure){ var cookieTxt=decodeURIComponent(name)+"="+decodeURIComponent(value); //过期时间 if(expires instanceof Date){ cookieTxt=cookieTxt+"; expires="+expires.toGMTString(); } if(path){ cookieTxt=`${cookieTxt}; path=${path}`; } if(domain){ cookieTxt=`${cookieTxt}; domain=${domain}`; } if(secure){ //secure非键值对,是一个secure的字符串 cookieTxt=`${cookieTxt}; ${secure}`; } // console.log(cookieTxt); document.cookie=cookieTxt; }, };
有了上面的添加cookie和删除cookie的方法,就可以使用了。我写了这样一段代码:
var date=new Date(); CookieUtil.set("book","love U!",date); console.log('浏览器中的cookie',document.cookie); var getInfo=CookieUtil.get("book") console.log('获得cookie',getInfo);
在node环境中运行,发现控制台给我报了一个错误:
document is not defined
为什么呢?document不是window的对象吗?js文件默认的对象是window,所以省略不写也没有问题啊?我不明白,于是在document前加了window,但还是同样的错误。于是找了网上的回答。
渣英语翻译一下:document是一个浏览器的dom对象,而node.js只是一个服务器,并不是js的浏览器,因此你不能用它获取浏览器的dom。
所以我就把这段代码复制到浏览器的控制台上,发现set成功了,第一个cookie是就是set后的结果,但是get还是get不到啊。
然后我就发现是我最上面的那个代码写错了,decode是解码,encode是编码啊。我两个给弄混了。
4、global对象的URI编码方法
URI:Uniform Resource Identifiers,通用资源标识符。
而encodeURI、decodeURI、encodeURIComponent、decodeURIComponent这四个方法,只是对URI进行编码,以便发送给浏览器。他们用特殊的UTF-8编码来替换所有无效的字符,从而让浏览器理解和接受。
-
为了理解encodeURI、decodeURI、encodeURIComponent、decodeURIComponent四个方法到底是什么,通过代码输出一下:
var str1=encodeURI("happy"); console.log(str1);//happy var str2=encodeURIComponent("sad"); console.log(str2);//sad var str3=decodeURI("angry"); console.log(str3);//angry var str4=decodeURIComponent("cry"); console.log(str4);//cry console.log(encodeURIComponent("http://www.w3school.com.cn"))//http%3A%2F%2Fwww.w3school.com.cn console.log(encodeURIComponent("http://www.w3school.com.cn/p 1/"))//http%3A%2F%2Fwww.w3school.com.cn%2Fp%201%2F console.log(encodeURIComponent(",/?:@&=+$#"))//%2C%2F%3F%3A%40%26%3D%2B%24%23 console.log(encodeURI("http://www.w3school.com.cn"))//http://www.w3school.com.cn console.log(encodeURI("http://www.w3school.com.cn/p 1/"))//http://www.w3school.com.cn/p%201/ console.log(encodeURI(",/?:@&=+$#"))//,/?:@&=+$#
先来看一下encodeURIComponent和encodeURI。
encodeURI是不会对属于自己的URI特殊符号进行编码。例如冒号、正斜杠、问号和井字号。
而encodeURIComponent是对整个地址中所有不符合规则的路径进行编码,即会对它发现的任何非标准字符进行编码。
在cookie中,一般用encodeURIComponent进行编码。
二、Web存储机制
Web存储机制目的是:
(1)为了克服cookie的限制,它的数据存在客户端上,不用发送给服务器。但浏览器关闭的时候,存储的信息就消失了。
(2)提供一种存储大量可以跨会话存在的数据机制
Web存储机制包括两种对象:sessionStorage和globalStorage。这两个对象在浏览器中是以window对象属性的形式存在的。
还记得在事件对象里面,IE浏览器的事件event 是作为window的属性存在的。现在,浏览器的window属性又多了两个。
Storage类型包含的方法有5种:
(1)clear(): 删除所有值
(2)getItem(name): 根据name获取对应的值。
(3)setItem(name, value): 根据name设置对应的值。
(4)removeItem(name): 删除name对应的值。
(5)key(index):获得index位置处值的名字。
sessionStorage是Storage的一个实例,所以可以使用Storage的各种方法,比如setItem方法。这些数据在浏览器关闭之后就会消失,但是跨页面刷新仍然存在。
sessionStorage.setItem("name","Alice"); //使用方法来存值,建议用这种
sessionStorage.book="如何学好JS"; //使用属性来存值,不建议使用
2、globalStorage空间的访问
他把信息存储在了电脑磁盘上。要想获取这些数据,必须先指定哪些域可以访问该数据。他是根据发起请求页面的域名、协议、端口来限制的。类似于ajax的同源策略。
如果用户长期未清理浏览器缓存,存储在globlastorage属性中的数据会一直保留。
3、localStorage
localStorage取代了globalStorage,不需要给localStorage指定任何访问规则,规则早就设置好了。
localStorage也是Storage的一个实例,也可以使用Storage的五种方法,就像sessionStorage一样。
localStorage.setItem('name', 'Alice'); //使用方法进行存取值,建议使用 localStorage.getItem('name'); localStorage.age = 18; //使用属性进行存取值,不建议使用 var age = localStorage.age;
三、IndexDB
indexDB是一个数据库,它的特点在于保存内容的时候,不是以表格的形式,而是以对象集合的形式。
1、数据库
使用indexDB的第一步,就是open()。如果数据库已存在,就会打开;如果不存在,就会创建并打开。
indexDB.open()会返回一个IDBRequest对象。在这个对象上,使用onerror和onsuccess事件处理程序。
var indexDB=window.indexedDB; function checkAll(){ var database; var request=indexDB.open("admin"); request.onerror=function(event){ console.log(event.target.errorCode); }; request.onsuccess=function(event){ database=event.target.result; }; }
看上面这段代码,分析一下。
首先打开的IDBRequest对象,赋给了request变量。而这个request变量,事件上就是事件中的属性target,所以,request其实就等于event.target。
而request这个对象中,存在的result属性,是一个数据库的实例对象。我们把这个对象赋给了database变量。
2、对象存储空间(增)
有了数据库,就要往数据库里增加和删除信息了。
在创建对象存储空间之前,首先要先清楚,你想要的保存什么数据类型。
取对象里面的某一个属性,作为对象存储空间的键。这个属性必须全局唯一,而我们就是通过这个键来访问数据。他是必需项。
var user={ username:"007", firstName:"Wang", lastName:"Huahua", password:"123" } var store=db.createObjectStore("users",{keypath:"username"});
分析上面这段代码,假设我们要记录的一个对象格式,是user这样的格式。取user对象里面的username作为键,创建一个对象存储空间。
createObjectStore里的第一个参数,是这个空间的名字,第二个参数,就是键了。
使用add()和put()方法,用来向这个空间添加数据。
var user1={ username:"007", firstName:"Wang", lastName:"Huahua", password:"123" }, var user2={ username:"007", firstName:"Wang", lastName:"Huahua", password:"123" } var store=db.createObjectStore("users",{keypath:"username"}); var users=[user1,user2] var i=0; while(i<users.length){ store.add(users[i++]); }
add与put的区别是:如果存在同名对象,add会报错,put会覆盖。
3、事务(改、查)
transaction()方法,创建事务。