cookie和session都是跟踪整个会话过程的技术手段。而会话,就是用户经过浏览器和服务器的一次通话。php
由于HTTP协议是无状态的,服务器不知道用户上一次作了什么,这严重阻碍了交互式web应用程序的实现。HTTP不经过额外的手段,服务器并不知道用户作了什么,为了作到这一点,就须要使用cookie和session了。服务器能够设置或者读取cookie中包含信息,借此维护用户跟服务器会话中的状态。html
cookie工做原理web
cookie分为两种数据库
cookie工做原理::::跨域
cookie的工做原理,这须要有基本的HTTP协议基础。浏览器
cookie是在RFC2109(已废弃,被RFC2965取代)里初次被描述的,每一个客户端最多保持三百个cookie,每一个域名下最多20个Cookie(实际上通常浏览器如今都比这个多,如Firefox是50个),而每一个cookie的大小为最多4K,不过不一样的浏览器都有各自的实现。对于cookie的使用,最重要的就是要控制cookie的大小,不要放入无用的信息,也不要放入过多信息。安全
不管使用何种服务端技术,只要发送回的HTTP响应中包含以下形式的头,则视为服务器要求设置一个cookie:
Set-cookie:name=name;expires=date;path=path;domain=domain服务器
支持cookie的浏览器都会对此做出反应,即建立cookie文件并保存(也多是内存cookie),用户之后在每次发出请求时,浏览器都要判断当前全部的cookie中有没有没失效(根据expires属性判断)而且匹配了path属性的cookie信息,若是有的话,会如下面的形式加入到请求头中发回服务端: Cookie: name="zj"; Path="/linkage" 服务端的动态脚本会对其进行分析,并作出相应的处理,固然也能够选择直接忽略。
cookie机制Cookies是服务器在本地机器上存储的小段文本并随每个请求发送至同一个服务器。IETF RFC 2965 HTTP State Management Mechanism 是通用cookie规范。网络服务器用HTTP头向客户端发送cookies,在客户终端,浏览器解析这些cookies并将它们保存为一个本地文件,它会自动将同一服务器的任何请求缚上这些cookies 。cookie
具体来讲cookie机制采用的是在客户端保持状态的方案。它是在用户端的会话状态的存贮机制,他须要用户打开客户端的cookie支持。cookie的做用就是为了解决HTTP协议无状态的缺陷所做的努力。
正统的cookie分发是经过扩展HTTP协议来实现的,服务器经过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。然而纯粹的客户端脚本如JavaScript也能够生成cookie。而cookie的使用是由浏览器按照必定的原则在后台自动发送给服务器的。浏览器检查全部存储的cookie,若是某个cookie所声明的做用范围大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器。网络
cookie的内容主要包括:名字,值,过时时间,路径和域。路径与域一块儿构成cookie的做用范围。若不设置过时时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie通常不存储在硬盘上而是保存在内存里,固然这种行为并非规范规定的。若设置了过时时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过时时间。存储在硬盘上的cookie能够在不一样的浏览器进程间共享,好比两个IE窗口。而对于保存在内存里的cookie,不一样的浏览器有不一样的处理方式。
而session机制采用的是一种在服务器端保持状态的解决方案。同时咱们也看到,因为采用服务器端保持状态的方案在客户端也须要保存一个标识,因此session机制可能须要借助于cookie机制来达到保存标识的目的。而session提供了方便管理全局变量的方式 。
session是针对每个用户的,变量的值保存在服务器上,用一个sessionID来区分是哪一个用户session变量,这个值是经过用户的浏览器在访问的时候返回给服务器,当客户禁用cookie时,这个值也可能设置为由get来返回给服务器。
就安全性来讲:当你访问一个使用session 的站点,同时在本身机子上创建一个cookie,建议在服务器端的session机制更安全些,由于它不会任意读取客户存储的信息。
再看一下session的原理:
session机制
session机制是一种服务器端的机制,服务器使用一种相似于哈希表的结构(也可能就是使用哈希表)来保存信息。
当程序须要为某个客户端的请求建立一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),若是已包含则说明之前已经为此客户端建立过session,服务器就按照session id把这个session检索出来使用(检索不到,会新建一个),若是客户端请求不包含session id,则为此客户端建立一个session而且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。
保存这个session id的方式能够采用cookie,这样在交互过程当中浏览器能够自动的按照规则把这个标识发挥给服务器。通常这个cookie的名字都是相似于SEEESIONID。但cookie能够被人为的禁止,则必须有其余机制以便在cookie被禁止时仍然可以把session id传递回服务器。
常常被使用的一种技术叫作URL重写,就是把session id直接附加在URL路径的后面。还有一种技术叫作表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时可以把session id传递回服务器。
Cookie与Session都可以进行会话跟踪,可是完成的原理不太同样。普通情况下两者均可以知足需求,但有时分不可以运用Cookie,有时分不可以运用Session。下面通过比拟阐明两者的特性以及适用的场所。
cookie生命周期:
若是cookie不设定时间的话就表视它的生命周期为浏览器会话的期间,只要关闭浏览器,cookie就消失了。若是设置了cokie的过时时间.那么浏览器会把cookie保存到硬盘中,再次打IE时会依然有效.直到超过设置的有效期,$.cookie(key, value, {path:"/", expire: new Date("2017-01-01")}) 设置过时时间。注:存储在硬盘中的cookie能够在不一样IE间共享。
session生命周期:
服务器会把长时间没有活动的Session从服务器内存中清除,此时Session便失效。Tomcat中Session的默认失效时间为20分钟。调用Session的invalidate方法。注:当禁用cookie时也是不能使用session的。
PHP中的session有效期默认24分钟,也就是说,客户端超过24分钟,当前session就会失效。固然,也能够经过session.gc_maxlifetime修改。
每一次php请求,会有1/100的几率(默认值)触发“session回收”。若是“session回收”发生,那就会检查
/tmp/sess_*的文件,若是最后的修改时间到如今超过了1440秒(gc_maxlifetime的值),就将其删除,意味着这些session过时失效。
因为PHP的工做机制,它并无一个daemon线程,来定时地扫描session信息并判断其是否失效。当一个有效请求发生时,PHP会根据全局变量session.gc_probability/session.gc_divisor(一样能够经过php.ini或者ini_set()函数来修改)的值,来决定是否启动一个GC(Garbage Collector)。默认状况下,session.gc_probability =1,session.gc_divisor =100,也就是说有1%的可能性会启动GC。
GC 的工做,就是扫描全部的session信息,用当前时间减去session的最后修改时间(modifieddate),同session.gc_maxlifetime参数进行比较,若是生存时间已经超过gc_maxlifetime,就把该session删除。
默认状况下,每一次php请求,就会有1/100的几率发生回收,因此可能简单的理解为“每100次php请求就有一次回收发生”。这个几率是经过如下参数控制的
几率是gc_probability/gc_divisor
session.gc_probability = 1
session.gc_divisor = 100
注意1:假设这种状况gc_maxlifetime=120,若是某个session文件最后修改时间是120秒以前,那么在下一次回收(1/100的几率)发生前,这个session仍然是有效的。
注意2:若是你的session使用session.save_path中使用别的地方保存session,session回收机制有可能不会自动处理过时session文件。这时须要定时手动(或者crontab)的删除过时的session:cd /path/to/sessions; find -cmin +24 | xargs rm
session.gc_maxlifetime
session.gc_probability
session.gc_divisor
session.gc_divisor 与 session.gc_probability 合起来定义了在每一个会话初始化时启动 gc(garbage collection 垃圾回收)进程的几率。此几率用 gc_probability/gc_divisor 计算得来。例如 1/100 意味着在每一个请求中有 1% 的几率启动 gc 进程。session.gc_divisor 默认为 100。
好比:session.gc_maxlifetime=30,session.gc_divisor=1000,session.gc_probability=1,就表示每一千个用户调用session_start()的时候,就百分百的会执行一次垃圾回收机制,将磁盘上没用的session文件删除。
注意:通常对于一些大型的门户网站,建议将session.gc_divisor调大一点,减小开销
接下来,我经过一个例子演示下,如何配置才能让调用gc(垃圾回收)进程呢!
经过配置php.ini文件,修改如下几个信息:
session.gc_maxlifetime = 60//当session文件在60s后尚未被访问的话,则该session文件将会被视为“垃圾文件”,而且等待gc(垃圾回收)进程的调用的时候被清理掉
session.gc_probability = 1000
由于gc进程被调用的几率是经过gc_probability/gc_divisor 计算得来的,这里我将session.gc_probability改为1000,而session.gc_divisor 默认状况下也是1000。则gc进程在每次执行session_start()函数的时候都会被调用到。
如下我经过截图简单的说明下:
我开启三个会话,则建立三个对应的session文件,当每一个文件在30秒内都没被调用的话,就会被当成是“垃圾文件”,等到gc进程调用的时候,“垃圾文件”就会被unlink,由于以前我已经经过修改php.ini配置文件,将gc被调用的几率改为百分百,因此接下来,若是我从新使用任何一个浏览器刷新下页面的时候,三个session文件,应该只剩下一个了
其实让Session结束生命周期,有如下两种办法:
* 一个是Session.invalidate()方法,不过这个方法在实际的开发中,并不推荐,可能在强制注销用户的时候会使用; * 一个是当前用户和服务器的交互时间超过默认时间后,Session会失效
咱们知道Session是存在于服务器端的,当把浏览器关闭时,浏览器并无向服务器发送任何请求来关闭Session,天然Session也不会被销毁,可是能够作一点努力,在全部的客户端页面里使用js的window.onclose来监视浏览器的关闭动做,而后向服务器发送一个请求来关闭Session,可是这种作法在实际的开发中也是不推荐使用的,最正常的办法就是不去管它,让它等到默认的时间后,自动销毁。
SESSION发出去的COOKIE通常属于即时COOKIE,保存在内存中,当浏览器关闭后,才会过时,假如须要人为强制过时,好比 退出登陆,而不是关闭浏览器,那么就须要在代码里销毁SESSION,方法有不少,
使用URL重写,就是把session id直接附加在URL路径的后面,做为URL路径的附加信息。
( 当客户端的Cookie被禁用或出现问题时,PHP会自动把Session ID附着在URL中,这样再经过Session ID就能跨页使用Session变量了。)
一般状况下 Cookie 里记录了 Session 的 id ,全部 Cookie 被禁用了也就意味着 Session 失效了。不过 Session id 还有另一种传递方式,就是在 URL 查询中携带 Session id (既把全部的URL里都带上Session id的参数,如: http://xxx/index?sid=...)。不够这种方法比较麻烦(全部的连接都要带上),并且比较容易丢失 Session id(地址能够认为修改去掉ID),全部只是做为备选方案,在 Cookie 不能使用的环境下能够做为替代。
常见的session实现方式是基于cookie的,因此禁用cookie,session随之失效
理论上只要在返回的页面里里能带上一个标识会话的令牌,在浏览器下一次提交的时候,能带上这个令牌,会话就能够被保持
所以,cookie只是最优雅的实现session的方式,由于cookie对用户来讲不可见,同时会自动在HTTP报文中传输
但session也能够经过其余方式来保持, 好比放一个sessionId在URL的参数里
关闭浏览器不能结束一个会话,.
session只是失效,可是并未被清除,关闭浏览器不等于退出登陆/结束会话了.....
那当咱们关闭浏览器以后,服务器端原来的session对象是否还存在呢?
答案是确定的。服务端根本不知道咱们是否关闭了浏览器,也不关心这个。客户端与服务端之间进行通讯的惟一途径就是经过请求。服务器有本身的一套机制来管理session,好比多长时间会清除没有使用过的session对象,等等。
那么为何当咱们关闭浏览器后,就再也访问不到以前的session了呢?
因此说,关闭浏览器session就被清除只是咱们所看到的表面现象(其实是新建了一个session对象),一般状况下,服务器并不会立刻清除session对象,但这个根据服务端的设定而不一样。
.0
其实以前的Session一直都在服务器.端,而当咱们关闭浏览器时,此时的Cookie是存在于浏览器的进程中的,当浏览器关闭时,Cookie也就不存在了。
其实Cookie有两种:
* 一种是存在于浏览器的进程中; * 一种是存在于硬盘上
而session的Cookie是存在于浏览器的进程中,那么这种Cookie咱们称为会话Cookie,
当咱们从新打开浏览器窗口时,以前的Cookie中存放的Sessionid已经不存在了,此时
服务器从HttpServletRequest对象中没有检查到sessionid,服务器会再发送一个新的存
有Sessionid的Cookie到客户端的浏览器中,此时对应的是一个新的会话,而服务器上
原先的session等到它的默认时间到以后,便会自动销毁。
...so,以此类推
当在同一个浏览器中同时打开多个标签,发送同一个请求或不一样的请求,还是同一个session;
当不在同一个窗口中打开相同的浏览器时,发送请求,还是同一个session;
当使用不一样的浏览器时,发送请求,即便发送相同的请求,是不一样的session;
当把当前某个浏览器的窗口全关闭,再打开,发起相同的请求时,就是本文所阐述的,是不一样的session,可是它和session的生命周期是没有关系的.
PS:cookie通常分为两种:一种是会话cookie,即服务端为session自动建立的cookie,这个cookie存放在浏览器进程中。另外一种是能够存放在硬盘上的,能够经过服务端的某些设置,将一些信息放到cookie中并返回给客户端存放在硬盘上。
Session是在客户端请求到达服务器时,服务器为此请求发出的客户所建立的一个对象,保存在服务器端。购物车是一个很好的例子,一个用户能够有不少session,但每一个session只针对一个用户,这就保证了不一样session之间的信息独立。
首先说明一点,在一般意义上,session所能发挥做用是基于cookie机制。针对所须要解释的问题,作这样一个假设:咱们第一次访问一个网页。当客户端发送请求后,服务端会创建一个针对此请求发出客户的session对象,并且每一个session都会有一个sessionID。服务端会自动将这个sessionID做为一个cookie附加到response上返回给客户端,这个cookie存放在浏览器内存中。咱们每次对此网页发送的request都会附带着这个cookie,服务端收到这个请求后会都去cookie中取得这个sessionID,而后查询服务端是否存在一个对应此ID的session对象。若是有,能够直接使用此session;若是没有,则会新建一个。当浏览器关闭后,其所占的内存就会是放掉,cookie天然也就被清除了,此时咱们再也不保存有这个sessionID。因此再打开浏览器访问同一个页面时,因为没有sessionID,也就查不到对应的session对象,此时从新建立一个新的session对象。
存储位置,隐私策略和安全性,数据类型,有效期,服务器压力,浏览器支持,跨域支持,数据量
1 .数据类型的不一样
Cookie中只能保管ASCII字符串,假如需求存取Unicode字符或者二进制数据,需求先进行编码。Cookie中也不能直接存取Java对象。若要存储略微复杂的信息,运用Cookie是比拟艰难的。
而Session中可以存取任何类型的数据,包括而不限于String、Integer、List、Map等。Session中也可以直接保管Java Bean乃至任何Java类,对象等,运用起来十分便当。可以把Session看作是一个Java容器类。
2 .隐私策略的不一样
Cookie存储在客户端阅读器中,对客户端是可见的,客户端的一些程序可能会窥探、复制以致修正Cookie中的内容。而Session存储在服务器上,对客户端是透明的,不存在敏感信息泄露的风险。
假如选用Cookie,比较好的方法是,敏感的信息如帐号密码等尽可能不要写到Cookie中。最好是像Google、Baidu那样将Cookie信息加密,提交到服务器后再进行解密,保证Cookie中的信息只要本人能读得懂。而假如选择Session就省事多了,反正是放在服务器上,Session里任何隐私都可以有效的保护。
3.有效期上的不一样
使用过Google的人都晓得,假如登陆过Google,则Google的登陆信息长期有效。用户不用每次访问都从新登陆,Google会持久地记载该用户的登陆信息。要到达这种效果,运用Cookie会是比较好的选择。只须要设置Cookie的过时时间属性为一个很大很大的数字。
因为Session依赖于名为JSESSIONID的Cookie,而Cookie JSESSIONID的过时时间默许为–1,只需关闭了阅读器该Session就会失效,于是Session不能完成信息永世有效的效果。运用URL地址重写也不能完成。并且假如设置Session的超时时间过长,服务器累计的Session就会越多,越容易招致内存溢出。
4.服务器压力的不一样
Session是保管在服务器端的,每一个用户都会产生一个Session。假如并发访问的用户十分多,会产生十分多的Session,耗费大量的内存。于是像Google、Baidu、Sina这样并发访问量极高的网站,是不太可能运用Session来追踪客户会话的。
而Cookie保管在客户端,不占用服务器资源。假如并发阅读的用户十分多,Cookie是很好的选择。关于Google、Baidu、Sina来讲,Cookie或许是惟一的选择。
5.浏览器支持的不一样
Cookie是须要客户端浏览器支持的。假如客户端禁用了Cookie,或者不支持Cookie,则会话跟踪会失效。关于WAP上的应用,常规的Cookie就派不上用场了。
假如客户端浏览器不支持Cookie,须要运用Session以及URL地址重写。须要注意的是一切的用到Session程序的URL都要进行URL地址重写,不然Session会话跟踪还会失效。关于WAP应用来讲,Session+URL地址重写或许是它惟一的选择。
假如客户端支持Cookie,则Cookie既可以设为本浏览器窗口以及子窗口内有效(把过时时间设为–1),也可以设为一切阅读器窗口内有效(把过时时间设为某个大于0的整数)。但Session只能在本阅读器窗口以及其子窗口内有效。假如两个浏览器窗口互不相干,它们将运用两个不一样的Session。(IE8下不一样窗口Session相干)
6.跨域支持上的不一样
Cookie支持跨域名访问,例如将domain属性设置为“.biaodianfu.com”,则以“.biaodianfu.com”为后缀的一切域名均可以访问该Cookie。跨域名Cookie现在被广泛用在网络中,例如Google、Baidu、Sina等。而Session则不会支持跨域名访问。Session仅在他所在的域名内有效。
仅运用Cookie或者仅运用Session可能完成不了理想的效果。这时应该尝试一下同时运用Cookie与Session。Cookie与Session的搭配运用在实践项目中会完成不少意想不到的效果。
7.存储数据量不一样
单个cookie保存的数据不能超过4k,不少浏览器都限制一个站点最多保存20个cookie
8.session和cookie的使用场景?
将登录信息等重要信息存放为SESSION;其余信息若是须要保留,能够放在COOKIE中。