刚刚考完研帮老师做一个apache ab的压力测试,结果做的过程中看到参数里面有一个cookie,想到当初做项目的时候只是为了赶紧完成功能没有好好理解cookie和session,于是好好看了几篇文章研究一下这个东西。以前学一些概念和知识看完了用完了过一段时间就忘记了。所以以后想要养成一个写博客的习惯,只有在写的过程中才能真正的理解知识并加入自己的想法,希望这篇文章能开个好头。
我个人的理解方式比较倾向于通俗化,从小到大对于所有的东西都是如此。能简单说出来道理的绝对没有必要搞得那么复杂。所以我希望以后的文章能在保持严谨的情况下尽可能的以一种通俗的方式表达自己的想法。废话不多说,开始正题吧。
-
综述
Cookie和Session都是为了解决Http无状态的问题。所谓无状态就是缺乏记忆能力,每一次的请求都是独立的。但是在实际的应用中经常会遇到当下的请求需要之前的数据或者状态。最简单的两个例子:购物车和登陆系统。首先是登陆系统,用户登陆以后,如果系统是无状态的,那么他使用系统的任何功能都需要不断重复的登陆才能确保是这个用户在使用系统,这显然是不合理的。而且在实际的使用中我们会发现如果第一天登陆了第二天就不用登陆了,这个就是cookie的典型应用。对于购物车来说,如果用户在商品选择页面选择了一系列商品,然后进入购买页面购买,如果是无状态的那么久无从知道他选了什么商品,如果这些信息都存在数据库一次一次的查未免也太过麻烦了。
上述两个例子可以看出,在系统的使用过程中会经常的需要使用一些以前产生的数据或者状态,由于http是无状态的,所以这些信息有两种方式存储。第一种就是存在客户端,每次请求服务器的时候发送过去,然后服务器收到后比对或者使用,这就是cookie。但是由于cookie存储在客户端,容易被修改因此很不安全,而且只能传输String,英文,还有大小的限制,所以它适合少量的信息。如果说信息量大而且格式复杂,就需要使用另一种方式session,session存放在服务器端,理论上存储无限多,只要内存足够大,而且足够安全。所以我的理解下cookie和session都是一种缓存机制,只不过具体的实现以及功能和应用场景不同罢了,而且session的使用通常要使用cookie来配合完成,关于二者的具体介绍如下。
-
Cookie
cookie就是存储在客户端的数据,以键值对的形式保存和传输。我们随便打开一个网站比如百度,在地址栏输入javascript:alert(document.cookie)就会显示以下信息。这就是baidu这个网站的cookie,当然信息都已经被加密过了。这里要提一点就是不同域名的网站cookie不能共享,就算是image.goole和www.google都不能共享,必须是完全一样的域名,这个工作是由浏览器帮我们完成的,对于我们来说是透明的。
关于cookie的时间问题,具体可以设置的。如果不设置那么就只能保存在这一次会话里面,关了浏览器就没了,那么这个时候cookie存在内存中,叫做transient cookie,另一种是永久存储,那就是在硬盘中,叫做permanent cookie。
在http中cookie到底是怎么工作的呢?如下图所示。有两个http头部是专门负责设置以及发送cookie的,它们分别是Set-Cookie以及Cookie。当服务器返回给客户端一个http响应信息时,其中如果包含Set-Cookie这个头部时,意思就是指示客户端建立一个cookie,并且在后续的http请求中自动发送这个cookie到服务器端,直到这个cookie过期。如果cookie的生存时间是整个会话期间的话,那么浏览器会将cookie保存在内存中,浏览器关闭时就会自动清除这个cookie。另外一种情况就是保存在客户端的硬盘中,浏览器关闭的话,该cookie也不会被清除,下次打开浏览器访问对应网站时,这个cookie就会自动再次发送到服务器端。一个cookie的设置以及发送过程分为以下四步:
关于使用cookie永久登陆有下面这个思路,一般来说是登陆成功以后将用户名密码保存成cookie发送再查询数据库,但是还可以将用户名加密以后,将用户名和加密结果保存为cookie传送过去,服务端将用户名再次加密与客户端传送过来的加密结果比较,如果相同就成功。
-
Session
Session是保存在服务端的一种缓存机制。每个用户在访问服务端后会创建一个session,每个session对应唯一的sessionid,用户通过sessionid来获得自己的session,那么这里就可以使用cookie来传送sessionid。这个过程应该也是透明的,我们不用管。如果cookie被禁用,就只能使用url重定向,将sessionid放在url后面当作一个参数。session可以是任何java类型,所以使用起来比cookie更方便。这个同样也可以使用在登陆中。在jsp页面中如果登陆成功可以使用session.setAttribute方法设置session,在welcome.jsp中使用session.getAttribute获得用户的信息。