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框架出来,当然这是后话了,之后可能会写一篇文章专门将这个。

posted @ 2015-11-02 22:59  五月的仓颉  阅读(2497)  评论(3编辑  收藏  举报