session和cookie
为什么我们要使用session和cookie
为什么要使用session和cookie这个话题就要从HTTP状态协议的无状态性开始说起了。
无状态协议是指协议对事物处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它应答就很快。
HTTP是超本文传输协议,顾名思义,这个协议支持超文本的传输。什么是超文本?说白了就是使用HTML编写的页面。通常,我们使用客户端浏览器访问服务器的资源,最常见的URL也是以html为后缀的文件,因此可以说超文本是网络上最主要的资源。
既然HTTP协议的目的是在于支持超文本的传输,也就是资源的传输,那么客户端浏览器向HTTP服务器发送请求,继而HTTP服务器将相信资源发回给客户端这样一个过程中,无论对于客户端还是服务器,都没有必要记录这个过程,因为每一次请求和响应都是相对独立的,就像我们在自动售货机前投下硬币购买商品一样,没必要记录这个交易过程。一般而言,一个URL对应着一个唯一的超文本,而HTTP服务器也绝对公平公正,无论是谁,都会根据接收到的URL请求返回相同的超文本。正是因为这样的唯一性,使得记录用户的行为状态变得毫无意义,所以,HTTP协议被设计为无状态的连接协议符合它本身的需求。
HTTP协议这种特性有优点也有缺点,优点在于解放了服务器,每一次请求"点到为止",不会造成不必要的连接占用,缺点在于每次请求都会传输大量的重复信息内容。
为了解决HTTP传输大量重复信息内容的问题,cookie和session就登场了,它们可以为用户保存状态。
cookie
cookie是通过客户端保持状态的解决方案。从定义上说,cookie就是服务器发送给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息。
更具体一点说,当用户使用浏览器访问一个支持cookie的网站的时候,会有如下步骤:
1、用户会提供包括用户名在内的个人信息并且提交至服务器
2、服务器在向客户端会传相应的超文本的同时,发回这些个人信息。当然这些信息并不是存放在HTTP响应体(Response Body)中的,而是存放在HTTP响应头(Response Header)中的
3、当客户端浏览器收到来自服务器的响应之后,浏览器会将这些信息存放在一个统一的位置
4、之后,客户端再向服务器发送请求的时候,都会把相应的cookie再次返回至服务器,而这次,cookie信息则存放在HTTP请求头中了
比方说,我请求了一次http://www.sina.com.cn/,请求头中带了这么多cookie的信息:
可能觉得这个cookie比较乱,搞个清楚版本的:
简单解释一下这张表格:
1、NAME=VALUE,键值对,cookie包括session都是以键值对的形式存储的
2、Domain,指的是生成该Cookie的域名
3、Path,指的是该Cookie是在哪个路径下生成的
4、Expires / Max-Age,指的是该Cookie的过期时间/最大失效时间(即多少秒之后失效)
5、Size,这个很明显,指的是占用的字节大小
6、Secure,如果设置了这个属性,那么只会在SSH连接时才会回传该cookie
有了cookie这样的技术实现,服务器在接收到来自客户端浏览器的请求之后,就能够通过分析存放于请求头中的cookie信息得到来自客户端特有的信息,从而动态生成与客户端相对应的内容。cookie在电脑中的存放地址为:
我的电脑是Win8的,在C:\Users\dell1\AppData\Local\Microsoft\Windows\INetCache
也可以通过IE浏览器来打开:浏览器-->工具-->Internet选项-->浏览器历史记录-->设置-->查看文件
session
session是相对于cookie的另外一个解决方案,它是通过服务器来保持状态的。session指的是服务器为客户端所开辟的存储空间,在其中保存的信息就是用于保存状态的。
首先,session是服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同创建session的方法。在创建了session的同时,服务器会为该session生成唯一的sessionId,而这个sessionId被创建了之后,就可以调用session相关的方法往session中增加内容了,而这些内容只会保存在服务器中,发送到客户端的只有sessionId。当客户端再次发送请求时,会将这个sessionId带上,服务器收到请求之后就会根据sessionId找到对应的session,从而再次使用。这样的一个过程,让用户的状态得以保持。
其次,每个session都有一个sessionId,这个ID存放在哪里?有两种方式:
1、通过URL存取,URL会带上一个;jsessionId=xxxxxx等,这样每次重新请求的时候都传了sessionId给服务器
2、通过cookie存取(Tomcat默认如此),这种cookie是session cookie,区别于persistent cookies也就是我们常说的cookie,session cookie要注意的是存储在浏览器内存中(至于浏览器内存在哪里,这是和浏览器相关的,比方说我用的是360浏览器,那就在360se6\User Data\Default这个路径下)而不是写到硬盘上。程序一开始执行,服务器就生成一个sessionId并通过cookie携带客户端浏览器的缓存中,当下一次访问的时候,服务器先检测一下是否有这个cookie,如果有就取它的ID,如果没有就再生成一个。这就是为什么关闭浏览器之后,再进去session已经没有了,其实在服务器端session并没有清空,而是sessionId变了。
再者,浏览器关闭,session没有了的说法是不正确的。如果浏览器关闭,服务器保存的session数据不是立即释放的,此时数据还会存在,只要我们知道那个sessionId,就可以继续通过请求获得此session的信息。session里面的数据都放在服务器端,通过sessionId保证不会访问错误,服务端自动对session进行管理,如果在规定的时间内没有访问,则释放掉这个session。
最后提两点:
1、sessionId通常是看不到的,但是当我们把浏览器的cookie禁止之后,Web服务器会采用URL重写的方式传递sessionId,这样就可以在地址栏看到sessionId了
2、session cookie不可以跨窗口使用
再谈cookie和session
cookie和session各有优缺点,在大型互联网系统中,单独使用cookie和session都是不可行的,使用cookie有如下缺点:
1、使用cookie来传递信息,随着cookie个数的增多和访问量的增加,它占用的网络带宽也很大,试想假如cookie占用200字节,如果一天的PV有几个亿,那么它要占用多少带宽?
2、cookie并不安全,因为cookie是存放在客户端的,所以这些cookie可以被访问到,设置可以通过插件添加、修改cookie。所以从这个角度来说,我们要使用sesssion,session是将数据保存在服务端的,只是通过cookie传递一个sessionId而已,所以session更适合存储用户隐私和重要的数据
不过session也有缺点:
1、不容易在多态服务器之间共享,这是致命的弱点
2、session存放在服务器中,所以session如果太多会非常消耗服务器的性能
既然如此,我们就可以扬长避短,利用cookie和session各自优点,规避它们的缺点,开发一套分布式的session框架出来,当然这是后话了,之后可能会写一篇文章专门将这个。
我不能保证写的每个地方都是对的,但是至少能保证不复制、不黏贴,保证每一句话、每一行代码都经过了认真的推敲、仔细的斟酌。每一篇文章的背后,希望都能看到自己对于技术、对于生活的态度。
我相信乔布斯说的,只有那些疯狂到认为自己可以改变世界的人才能真正地改变世界。面对压力,我可以挑灯夜战、不眠不休;面对困难,我愿意迎难而上、永不退缩。
其实我想说的是,我只是一个程序员,这就是我现在纯粹人生的全部。
==================================================================================