Cookie
在学习一个新知识点前,我们应该明白自己的学习目标,要带着疑问去学习,该小节须要了解
Cookies
- 什么是cookie,cookie的作用
- cookie的工作机制,即cookie是运作流程
- cookie的基本属性(4个)以及我们如何使用cookie
什么是Cookie
HTTP协议本身是无状态的。什么是无状态呢,即服务器无法判断用户身份。
Cookie实际上是一小段的文本信息(key-value格式)。客户端向服务器发起请求,如果服务器需要记录该用户状态,就使用response向客户端浏览器发送一个Cookie,==通知客户端浏览器会把Cookie保存起来==。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。
打个比方,我们去银行办理储蓄业务,第一次给你办了张银行卡,里面存放了身份证、密码、手机等个人信息。当你下次再来这个银行时,银行机器能识别你的卡,从而能够直接办理业务。
cookie机制
当用户第一次访问并登录一个网站的时候,cookie的设置以及发送会经历以下4个步骤:
- 客户端发送一个请求给服务器
- 服务器发送一个
HttpResponse响应
给客户端,其中包含Set-Cookie
的头部 - 客户端保存cookie,之后向服务器发送请求时,HttpRequest请求中会包含一个Cookie的头部
- 服务器返回响应数据
为了探究这个过程,写了代码进行测试,如下:
我在doGet方法中,new了一个Cookie对象并将其加入到了HttpResponse对象中
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie = new Cookie("mcrwayfun",System.currentTimeMillis()+"");
// 设置生命周期为MAX_VALUE
cookie.setMaxAge(Integer.MAX_VALUE);
resp.addCookie(cookie);
}
浏览器输入地址进行访问,结果如图所示:
可见Response Headers中包含Set-Cookie头部,而Request Headers中包含了Cookie头部。name和value正是上述设置的。
cookie属性项
属性项 | 属性项介绍 |
---|---|
NAME=VALUE | 键值对,可以设置要保存的 Key/Value,注意这里的 NAME 不能和其他属性项的名字一样 |
Expires | 过期时间,在设置的某个时间点后该 Cookie 就会失效 |
Domain | 生成该 Cookie 的域名,如 domain="www.baidu.com" |
Path | 该 Cookie 是在当前的哪个路径下生成的,如 path=/wp-admin/ |
Secure | 如果设置了这个属性,那么只会在 SSH 连接时才会回传该 Cookie |
Expires
该属性用来设置Cookie的有效期。Cookie中的maxAge用来表示该属性,单位为秒。Cookie中通过getMaxAge()和setMaxAge(int maxAge)来读写该属性。maxAge有3种值,分别为正数,负数和0。
如果maxAge属性为正数,则表示该Cookie会在maxAge秒之后自动失效。浏览器会将maxAge为正数的Cookie持久化,即写到对应的Cookie文件中(每个浏览器存储的位置不一致)。无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该Cookie仍然有效。下面代码中的Cookie信息将永远有效。
Cookie cookie = new Cookie("mcrwayfun",System.currentTimeMillis()+"");
// 设置生命周期为MAX_VALUE,永久有效
cookie.setMaxAge(Integer.MAX_VALUE);
resp.addCookie(cookie);
当maxAge属性为负数,则表示该Cookie只是一个临时Cookie,不会被持久化,仅在本浏览器窗口或者本窗口打开的子窗口中有效,关闭浏览器后该Cookie立即失效。
Cookie cookie = new Cookie("mcrwayfun",System.currentTimeMillis()+"");
// MaxAge为负数,是一个临时Cookie,不会持久化
cookie.setMaxAge(-1);
resp.addCookie(cookie);
可以看到,当MaxAge为-1时,时间已经过期
当maxAge为0时,表示立即删除Cookie
Cookie[] cookies = req.getCookies();
Cookie cookie = null;
// get Cookie
for (Cookie ck : cookies) {
if ("mcrwayfun".equals(ck.getName())) {
cookie = ck;
break;
}
}
if (null != cookie) {
// 删除一个cookie
cookie.setMaxAge(0);
resp.addCookie(cookie);
}
那么maxAge设置为负值和0到底有什么区别呢?
maxAge设置为0表示立即删除该Cookie,如果在debug的模式下,执行上述方法,可以看见cookie立即被删除了。
maxAge设置为负数,能看到Expires属性改变了,但Cookie仍然会存在一段时间直到关闭浏览器或者重新打开浏览器。
修改或者删除Cookie
HttpServletResponse提供的Cookie操作只有一个addCookie(Cookie cookie),所以想要修改Cookie只能使用一个同名的Cookie来覆盖原先的Cookie。如果要删除某个Cookie,则只需要新建一个同名的Cookie,并将maxAge设置为0,并覆盖原来的Cookie即可。
新建的Cookie,除了value、maxAge之外的属性,比如name、path、domain都必须与原来的一致才能达到修改或者删除的效果。否则,浏览器将视为两个不同的Cookie不予覆盖。
值得注意的是,从客户端读取Cookie时,包括maxAge在内的其他属性都是不可读的,也不会被提交。浏览器提交Cookie时只会提交name和value属性,maxAge属性只被浏览器用来判断Cookie是否过期,而不能用服务端来判断。
我们无法在服务端通过cookie.getMaxAge()来判断该cookie是否过期,maxAge只是一个只读属性,值永远为-1。当cookie过期时,浏览器在与后台交互时会自动筛选过期cookie,过期了的cookie就不会被携带了。
Cookie的域名
Cookie是不可以跨域名的,隐私安全机制禁止网站非法获取其他网站的Cookie。
正常情况下,同一个一级域名下的两个二级域名也不能交互使用Cookie,比如test1.mcrwayfun.com和test2.mcrwayfun.com,因为二者的域名不完全相同。如果想要mcrwayfun.com名下的二级域名都可以使用该Cookie,需要设置Cookie的domain参数为.mcrwayfun.com,这样使用test1.mcrwayfun.com和test2.mcrwayfun.com就能访问同一个cookie
一级域名又称为顶级域名,一般由字符串+后缀组成。熟悉的一级域名有baidu.com,qq.com。com,cn,net等均是常见的后缀。
二级域名是在一级域名下衍生的,比如有个一级域名为mcrfun.com,则blog.mcrfun.com和www.mcrfun.com均是其衍生出来的二级域名。
Cookie的路径
path属性决定允许访问Cookie的路径。比如,设置为"/"表示允许所有路径都可以使用Cookie
Session
什么是Session
session是另一种记录客户状态的机制,==不同的是cookie保存在客户端浏览器中,而session保存在服务器上==。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是session。客户端浏览器再次访问时只需要从该session中查找该客户的状态就可以了。session相当于程序在服务器上建立的一份用户的档案,用户来访的时候只需要查询用户档案表就可以了。
Session 是一个接口(HttpSession,它是用来维护一个客户端和服务器之间关联的一种技术。
每个客户端都有自己的一个 Session 会话。
session的生命周期与有效期
为了获得更高的存取速度,服务器一般把session放在内存里。每个用户都会有一个独立的session。如果session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。session的使用虽然比cookie方便,但是过多的session存储在服务器内存中,会对服务器造成压力。因此,session里的信息应该尽量精简。
session在用户第一次访问服务器的时候自动创建。session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该session。
由于有越来越多的用户访问服务器,因此session也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的session从内存中删除。这个时间就是session的超时时间。如果超过了超时时间没访问过服务器,session就自动失效了
Session的工作机制
Session的工作机制离不开Cookie
虽然session保存在服务器,但是它的正常运行仍然需要客户端浏览器的支持。这是因为session需要使用cookie作为识别标志。HTTP协议是无状态的,session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为SESSIONID
的cookie,它的值为该Session的id。Session依据该cookie来识别是否为同一用户。
对于不支持cookie的手机浏览器,有另一种解决方案:URL地址重写。URL地址重写的原理是将该用户session的id信息重写到URL地址中,服务器能够解析重写后的URL获取session的id。这样即使客户端不支持cookie,也可以使用session来记录用户状态。
webstorage本地存储
webstorage是本地存储,存储在客户端,包括localStorage
和sessionStorage
- localStorage生命周期是永久,这意味着除非用户自己清除localStorage信息,否则这些信息将永远存在。存放数据大小为一般为5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务器的通信
- sessionStorage仅在当前会话下有效,关闭页面或浏览器后被清除。存放数据大小为一般为5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务器的通信
为什么会有WebStorage
提供一种在cookie之外存储会话数据的路径,提供一种存储大量跨会话存在的数据的机制
HTML5的WebStorage提供了两种API:localStorage(本地存储)和sessionStorage(会话存储)
localStorage和sessionStorage
- 作用域的不同
不同浏览器无法共享localStorage或sessionStorage中的信息。相同浏览器的不同页面间可以共享相同的 localStorage(页面属于相同域名和端口),但是不同页面或标签页间无法共享sessionStorage的信息。这里需要注意的是,页面及标 签页仅指顶级窗口,如果一个标签页包含多个iframe标签且他们属于同源页面,那么他们之间是可以共享sessionStorage的 - 存储大小
localStorage和sessionStorage的存储数据大小一般都是:5MB - 存储位置
localStorage和sessionStorage都保存在客户端,不与服务器进行交互通信 存储内容类型
localStorage和sessionStorage==只能存储字符串类型==,对于复杂的对象可以使用ECMAScript提供的JSON对象的stringify
和parse
来处理//存 var obj = {"name":"xiaoming","age":"16"} localStorage.setItem("userInfo",JSON.stringify(obj)); //取 var user = JSON.parse(localStorage.getItem("userInfo") //删除 localStorage.remove("userInfo); //清空 localStorage.clear();
获取方式
// localStorage window.localStorage; //sessionStorage window.sessionStorage;
应用场景
- localStoragese:常用于长期登录(+判断用户是否已登录),适合长期保存在本地的数据,
- sessionStorage:敏感账号一次性登录
WebStorage的优点:
- 存储空间更大:cookie为4KB,而WebStorage是5MB
- 节省网络流量:WebStorage不会传送到服务器,存储在本地的数据可以直接获取,也不会像cookie一样每次请求都会传送到服务器,所以减少了客户端和服务器端的交互,节省了网络流量,对于那种只需要在用户浏览一组页面期间保存而关闭浏览器后就可以丢弃的数据,sessionStorage会非常方便
- 快速显示:有的数据存储在WebStorage上,再加上浏览器本身的缓存。获取数据时可以从本地获取会比从服务器端获取快得多,所以速度更快
安全性:WebStorage不会随着HTTP header发送到服务器端,所以安全性相对于cookie来说比较高一些,不会担心截获,但是仍然存在伪造问题
- WebStorage提供了一些方法,数据操作比cookie方便
- setItem (key, value) —— 保存数据,以键值对的方式储存信息。
- getItem (key) —— 获取数据,将键值传入,即可获取到对应的value值。
- removeItem (key) —— 删除单个数据,根据键值移除对应的信息。
- clear () —— 删除所有的数据
- key (index) —— 获取某个索引的key
各种区别比较
Cookie | localStorage | sessionStorage | |
---|---|---|---|
生命周期 | 可自己设置,默认到浏览器关闭 | 浏览器关闭 | 除非自行删除,否在一直存在 |
大小 | 4K | 5MB | 5MB |
与服务器通信 | http请求头中 | 不参与服务器通信 | 仅在客户端 |
localStorage与cookie的区别
- cookie在浏览器与服务器之间来回传递
sessionStorage和localStorage不会把数据发给服务器,仅在本地保存 - 数据有效期不同
cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
sessionStorage:仅在当前浏览器窗口关闭前有效
localStorage 始终有效,长期保存 - cookie数据还有路径的概念,可以限制cookie只属于某个路径下
存储大小也不同,cookie数据不能超过4k,sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大 作用域不用
- sessionStorage在不同的浏览器不能共享
- localStorage在所有同源窗口中都是共享的
- cookie也是在所有同源窗口中都是共享的
- WebStorage 支持事件通知机制,可以将数据更新的通知发送给监听者。Web Storage 的 api 接口使用更方便
cookie、session和localStorage的区别
- cookie的内容主要包括:名字、值、过期时间、路径和域,路径与域一起构成cookie的作用范围。若不设置时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就会消失,这种生命期为浏览器会话期的cookie被称为会话cookie
- 会话cookie一般不存储在硬盘而是保存在内存里,当然这个行为并不是规范规定的。若设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再打开浏览器这些cookie仍然有效直到超过设定的过期时间。对于保存在内存里的cookie,不同的浏览器有不同的处理方式session机制。
- 当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(检索不到,会新建一个),如果客户端请求不包含session id,则为客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。
cookie和session的区别
- cookie数据存放在客户的浏览器上,session数据放在服务器上
- cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session
- session会在一定时间内保存在服务器上,当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie
- 单个cookie保存的数*据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie
- 建议将登录信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中
- session保存在服务器,客户端不知道其中的信心;cookie保存在客户端,服务器能够知道其中的信息
- session中保存的是对象,cookie中保存的是字符串
- session不能区分路径,同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到,而cookie中如果设置了路径参数,那么同一个网站中不同路径下的cookie互相是访问不到的
web Storage和cookie的区别
- Web Storage的概念和cookie相似,区别是它是为了更大容量存储设计的,cookie的大小是受限的,并且每次请求一个新的页面的时候cookie都会被发送过去,这样无形中浪费了带宽,另外cookie还需要指定作用域,不可跨域调用
- web storage拥有setItem,getItem,removeItem,clear等方法,不像cookie需要前端开发者自己封装setCookie,getCookie
- 但是cookie也是不可或缺的,cookie的作用是与服务器进行交互,作为http规范的一部分而存在的,而web Storage仅仅是为了在本地“存储”数据而生
sessionStorage、localStorage、cookie都是在浏览器端存储的数据,其中sessionStorage的概念很特别,引入了一个“浏览器窗口”的概念,sessionStorage是在同源的同窗口中,始终存在的数据,也就是说只要这个浏览器窗口没有关闭,即使刷新页面或进入同源另一个页面,数据仍然存在,关闭窗口后,sessionStorage就会被销毁,同时“独立”打开的不同窗口,即使是同一页面,sessionStorage对象也是不同的 - Web Storage的好处
减少网络流量:一旦数据保存在本地之后,就可以避免再向服务器请求数据,因此减少不必要的数据请求,减少数据在浏览器和服务器间不必要的来回传递
快速显示数据:性能好,从本地读数据比通过网络从服务器上获得数据快得多,本地数据可以及时获得,再加上网页本身也可以有缓存,因此整个页面和数据都在本地的话,可以立即显示
临时存储:很多时候数据只需要在用户浏览一组页面期间使用,关闭窗口后数据就可以丢弃了,这种情况使用sessionStorage非常方便
浏览器本地存储与服务器端存储的区别
- 数据既可以在浏览器本地存储,也可以在服务器端存储
- 浏览器可以保存一些数据,需要的时候直接从本地存取,sessionStorage、localStorage和cookie都是由浏览器存储在本地的数据
- 服务器端也可以保存所有用户的所有数据,但需要的时候浏览器要向服务器请求数据
- 服务器端可以保存用户的持久数据,如数据库和云存储将用户的大量数据保存在服务器端 ,服务器端也可以保存用户的临时会话数据,服务器端的session机制,如jsp的session对象,数据保存在服务器上
- 服务器和浏览器之间仅需传递session id即可,服务器根据session id找到对应用户的session对象,会话数据仅在一段时间内有效,这个时间就是server端设置的session有效期
- 服务器端保存所有的用户的数据,所以服务器端的开销较大,而浏览器端保存则把不同用户需要的数据分别保存在用户各自的浏览器中,浏览器端一般只用来存储小数据,而非服务可以存储大数据或小数据服务器存储数据安全一些,浏览器只适合存储一般数据
sessionStorage、localStorage和cookie的区别
- 相同点是都是保存在浏览器端、且同源的
- cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下
- 存储大小限制也不同,cookie数据不能超过4K,同时因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
- 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
- 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的
- web Storage支持事件通知机制,可以将数据更新的通知发送给监听者
- web Storage的api接口使用更方便
sessionStorage与页面js数据对象的区别
- 页面中一般的js对象的生存期仅在当前页面有效,因此刷新页面或转到另一页面这样的重新加载页面的情况,数据就不存在了
- sessionStorage只要同源的同窗口中,刷新页面或进入同源的不同页面,数据始终存在,也就是说只要浏览器不关闭,数据仍然存在
同源的判断规则
与URLhttp://www.example.com/dir/page.html
的对比。
参考文档
https://segmentfault.com/a/11...
https://www.sohu.com/a/207801...
https://blog.csdn.net/weixin_...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。