一、Cookie
概念: Cookie是一种客户端技术,将服务器的数据以Key-Value的形式保存在所属的客户端中。当再次访问服务器时,将会带着Cookie中的数据去访问.
特点:
<1> 存储位置。设置了过期时间的Cookie,数据存储在用户浏览器上,客户端的Cookies文件夹内;没有设置过期时间的Cookie,则保存在内存中.
<2> 存储限制。阅览器对Cookie的大小、数量存在限制,各个浏览器限制.
各浏览器之间对cookie的不同限制:
| IE6.0 | IE7.0/8.0/9.0+ | Opera | Firefox | Safari | Chrome | |
| cookie个数 | 每个域为20个 | 每个域为50个 | 每个域为30个 | 每个域为50个 | 没有个数限制 | 每个域为53个 |
| cookie大小 | 4095个字节 | 4095个字节 | 4096个字节 | 4097个字节 | 4097个字节 | 4097个字节 |
| 超过大小限制 | 忽略 | 忽略 | 忽略 | 忽略 | 忽略 | 忽略 |
| 超过数量限制 | 过期最老的 | 过期最老的 | 过期最老的 | 随机过期 | 无限制 | 过期最老的 |
数量方面可以记为IE6.0最小20个,其他一般为50个,Safari最大无限制。Cookie大小方面一般为4k。
<3> 一种写入客户端的手段。Cookie是一种服务器端往客户端写入数据的手段,应该也是客户端仅支持的一种方式。
<4> Cookie可以被客户端禁用。
扩展: 当Cookie被禁用时,可以使用URL重写来解决.
在不能用Cookie的系统中,可以将服务端的SessionID动态的添加进生成Html页面的各超链接或转发地址中。
具体步骤:
Java中提供两个方法response.encodeRedirectURL()和response.encodeURL()对URL进行重写。这两个方法主要区别是,response.encodeURL()使用在本应用级别,response.encodeRedirectURL()跨应用级别(PS:这里我查了资料,还是不太理解它具体所致,有了解的谈一下☺);它们都会为URL追加一个Jsessionid的参数。
String url = response.encodeRedirectURL("/home");
PrintWriter.println("<a href='"+url+"'>主页</a>"); <5> Cookie安全性较差。因为保存在本地,可以分析存放在本地的COOKIE并进行COOKIE欺骗,所以它固有安全上的弱点,因此Cookie不能用来保存保密信息,例如密码、卡号等信息。对于敏感数据应加密后使用。直接拷贝Cookie文件到浏览器下是不行的,需要骗过阅览器的保证时间。
<6> 存储数据类型。仅能保存ASCII字符串类型,如果使用UTF-8格式需要转码。Java代码实例:
//保存
Cookie cookie = newCookie("userName", URLEncoder.encode("Cookie测试","UTF-8"));
response.addCookie(cookie);
//读取
URLDecoder.decode(cookies[i].getValue(),"UTF-8")<7> 生命周期方面。该Cookie为服务器自动生成的,它的maxAge属性一般为-1,表示仅当前浏览器内有效;每个Cookie都有自己的过期时间,超过了过期时间后失效,如果要Cookie永久存在,可以在代码中如下设置:
cookie.setMaxAge(Integer.MAX_VALUE);<8> 浏览器间可共享。对于保存在阅览器文件夹中的Cookie,多个阅览器间可以共享。而对于保存在内存中的Cookie,不同预览器其处理不一致。
二、Session
<1> 存储位置。Session将文件存储在服务器端,默认保存在文件中。放在文件、数据库、内存中都可以,例如默认保存在文件中,也可以统一保存在Mysql、Redis。
<2> 无存储限制。理论上不存在任何存储限制,可以保存任意长度的数据。
<3> 安全性好。由于保存在服务器端,所以Session数据更加安全。
<4> Session失效机制。
(1) 设置Session的失效时间,当客户端过期时间内无再次访问,则失效。若再次访问,则刷新Session的时间。
容器中设置超时时间,以tomcat为例,在tomcat-7.0\conf\web.xml中设置。默认超时时间为30分钟,负数或0位永久有效,时间以服务器时间为参,时间单位为分钟:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
在项目中设置web.xml,以分钟为单位:
<session-config>
<session-timeout>15</session-timeout>
</session-config>
通过Java代码控制,以秒为单位:
session.setMaxInactiveInterval(30*60);(2) 调用Session的invalidate方法。
(3) 关闭阅览器,当Cookie设置为默认内存存储,关闭阅览器Cookie则失效。服务器端依然会保存Session,但是该Session一般无法被再次触发,在过期时间之后,会被自动清除。相当于Session已经无效。
<5>存储数据类型。可以存储任意的数据类型,Integer、String、Object等。
三、比较
通过上面认识Cookie和Session的特性,那么我可以得出如下比较:
<1> 存储位置不同:Cookie存储于用户阅览器中,默认保存在内存中,可以设置为保存Cookie文件夹中;Session存储于服务器端,默认保存于文件中,可以保存在文件、数据库、内存。
<2> 是否客户端可以禁用:Cookie可以被客户端禁用;Session不能被客户端禁用。
<3> 安全性不同:Cookie因存储于客户端,容易存在安全性问题;而Session存储于服务器端,相对来说更加安全。
<4> 生命周期不同:Cookie的生命周期是连续的,设置为20分钟,20分钟后会失效。而Session的生命周期是间断的,设置为20分钟,若再次访问,则重新开始计时。
<5> 存储数据支持不同:Cookie仅支持String;Session支持String、Integer、Object等多种数据格式。
<6> 存储限制不同:Cookie存在阅览器的存储限制;而Session基本不存在限制,主要看服务器的物理内存、存储设备大小 。
四、总结
说一下个人的理解,上面所说的Session我认为可以说是一种狭义的Session,一般是指服务器端一种会话存储的手段。但是从根本上来讲,会话的存在是因为HTTP本身是无状态的,所以Session广义上是一个维持用户状态的会话机制。而Cookie则是实现会话的一种客户端技术手段。例如你可以用下面这些技术方式实现会话机制:
(1) 使用加密的Cookie方式。尤其是在大量并发时,因为Session存储在服务器端,所以大量的用户状态会造成服务性能降低,所以可以使用纯Cookie来保存用户状态,而用加密来保障安全性。
(2) 使用Cookie+Servlet Session方式。在考虑到浏览器限制时,可以将用户信息保存在Session,而Cookie保存SessionId。
(3) 使用Cookie+Redis方式。在分布式时,多台机器如何维护会话状态,可以考虑使用Redis作为专门的会话维护的服务器。可以看出会话你可以当做是一种概念,而Cookie则是一种实现会话的技术手段,而我们常常说的Session也可以看做是一种实现会话的手段。
本文详细对比了Cookie与Session两种常用的技术手段,从存储位置、安全性、生命周期等方面进行了深入解析,并探讨了它们在实际应用中的优缺点。
275

被折叠的 条评论
为什么被折叠?



