cookie 和 session

首先简要的说一下 cookiesession 分别是用来干什么的?
cookie
可以用来跟踪会话,也可以用来保存用户喜好或者保存用户名密码;

session
用来跟踪会话;

下面内容来源于知乎上的回答,作者:郭无心,cookie 和 session 的区别,个人觉得这段原理解释非常通俗易懂,故在此引用。

保存用户名密码

当我们平时登录网站点击保存用户名和密码时,一般保存的都是 cookie,将用户名和密码的 cookie 保存到硬盘中,这样再次登录的时候浏览器直接将 cookie 发送到服务器端验证即可,这样对于用户来说很方便。直接将 uesernamepassword 保存到客户端,这当然是很不安全的,对此浏览器也可以进行加密解密,而每个浏览器都可以有自己的加密解密方式。

保存用户喜好

用户喜欢的网页背景色(比如 QQ 空间的背景),这些信息也是可以用个 cookie 保存到客户端的,这样登录之后浏览器就可以直接获取相应的偏好设置。

会话跟踪

比如某些网站中网页有不同的访问权限,有只能登录的用户访问的网页,或者用户级别不同不能访问的,但 http请求是无状态的,每次访问服务器端是不知道是否是登录用户。这样的话,我们很自然的会想到在 http 请求报文中加入登录标识,而这个登录标识就可以是 cookie。服务器端保存有所有登录用户的 cookie,这样请求报文来了之后,将登录标识 cookie 与服务器端的 cookie 进行比较即可。

再比如购物网站,多次点击添加商品都购物车,客户端很容易知道哪些物品在购物车中,但是服务器端怎么知道每次添加的物品放到哪个登录用户的购物车中呢?也需要请求报文中带着 cookie 才行(在不登录的情况下,京东也可以不断添加商品,推测应该是登录的时候一并创建 cookie 并且发送物品信息)。

这些 cookie 都是为了跟踪会话用的,所以客户端有,服务器端也有,并且服务器端有全部的会话 cookie

session

后来衍生出 session 技术,之所以出现 session 技术,主要是为了安全,而 session 技术需要用到 cookie

我们都知道,http 是无状态的协议,客户每次读取 web 页面时,服务器都会打开新的会话,而且服务器也不会自动维护客户的上下文信息,那么要怎么才能实现网上商店中的购物车呢? session 就是一种保存上下文信息的机制,它是针对每一个用户的,变量的值保存在服务器端,通过 SessionID 来区分不同的客户。sessioncookieURL 重写为基础,默认使用 cookie 来实现,系统会创造一个名为 JSESSIONID 的输出 cookie,我们把它称为 session cookie,以区别 persistent cookies(也即我们通常所说的 cookie)。这里需要注意的是,session cookie 是存储于浏览器内存中的,并不是写到硬盘上的,所以通常情况下我们是看不到 JSESSIONID 的,但是当我们把浏览器的 cookie 禁止后,web 服务器会采用 URL 重写的方式传递 SessionID,我们就可以在地址栏看到 sessionid=KWJHUG6JJM65HS2K6 之类的字符串。

HTTP 请求报文

HTTP 请求报文
上图中, HTTP 请求报文头的最后一行有 cookie,不过是 JSESSIONIDcookie 值。
一般 Cookie 形式如下:
Cookie:$Version=1;Skin=new;jsessionid=5F4771183629C9834F8382E23BE13C4C
前两个值为偏好设置,最后一个为 jsessionid。

服务器端是怎么知道客户端的多个请求是属于哪一个 Session 呢?
jsessionid,是通过 HTTP 请求报文头的 Cookie 属性的 jsessionid 的值关联起来的。(当然也可以通过重写 URL 的方式来将会话 ID 附带在每个 URL 后面)

以上,引用内容结束!


目的(用途)不同

cookie 可以用来跟踪会话,也可以用来保存用户喜好或者保存用户名密码,其主要是为了解决 HTTP 协议无状态的缺陷;
session 用来跟踪会话,主要是为了安全;

隐私策略(存储位置)不同

cookie 保存在客户端,对客户端是可见的。客户端的一些程序可能会窥探、复制甚至修改 cookie 中的内容,存在安全隐患;
session 保存在服务器端,对客户端是透明的,不存在敏感信息泄露的风险;

有效期不同

cookie
如果不设置过期时间,则表示这个 cookie 的生命周期为浏览器会话期间,关闭浏览器窗口,cookie 就消失。(会话 cookie,一般不存储在硬盘上,而是保存在内存中)
如果设置了过期时间,则只有超过了过期时间,cookie 才会消失。(这种情况下,浏览器会把 cookie 保存到硬盘上,存储在硬盘上的 cookie 可以在不同浏览器进程间共享)因此我们可以完成信息永久有效的效果,即设置 cookie 的过期时间属性为一个很大很大的数字即可。

session
session 依赖于 JSESSIONIDcookie,而 Cookie JSESSIONID 的过期时间默认为 -1,只要关闭浏览器窗口,该 session 就会失效。因此,它无法完成信息永久有效的效果。

服务器压力不同

前面在 存储位置不同 中提到了两者的存储位置。
cookie 保存客户端,不占服务器资源;如果并发访问的用户很多,cookie 是不错的选择;
session 保存在服务器端,每一个用户都会产生一个 sessionid,如果并发访问的用户很多,就会耗费大量的内存。

浏览器支持不同

cookie 需要客户端浏览器的支持。假如客户端禁用了 cookie,或者不支持 cookie,则会话跟踪就会失效。
而对于 session 而言,如果客户端浏览器持 cookiesession 可以通过重写 URL 的方式将 ID 附带在每个 URL 后面。

假如客户端支持 cookie,则 cookie 既能设为本浏览器窗口以及子窗口内有效(把过期时间设为 -1),也能设为一切浏览器窗口内有效(把过期时间设为某个大于 0 的整数);
session 只能在本浏览器窗口以及其子窗口内有效。

跨域支持上的不同

cookie 支持跨域名访问,例如将 domain 属性设置为 “.biaodianfu.com”,则以 “.biaodianfu.com” 为后缀的一切域名均能够访问该 cookie;
session 不支持跨域名访问,尽在它所在的域名内有效;

存储类型不同

cookie 中只能保管 ASCII 字符串,如果需要存储 Unicode 字符或者二进制数据,需要先进行编码;也不能存储 java 对象;
session 中能够存储任何类型的数据,包括且不仅限于 String、Integer、List、Map等;也能直接保管 Java 类,对象等;

补充内容

【Q1】 如何设置 cookie
cookie 是以键值对的形式保存的,即 key=value 的格式,各个 cookie 之间一般是以 “;” 分隔。

1
2
3
4
cookie.name = value;
document.cookie = "name" + uesername;
// 保存变量 username 的值('jack')到 cookie 中,key 值为 name

【Q2】 如何改变/设置 session 的有效期?
方法一
在主页面中写入下面两句:

1
2
HttpSession session = request.getSession(true);
session.setMaxInactiveInterval(3600); // 3600秒(服务器端的3600秒,而不是客户端的)

方法二
在项目的 web.xml 中设置:

1
2
3
4
<session-config>
<session-timeout>60</session-timeout>
<session-config>
// 60 指的是 60 分钟

您的支持将鼓励我继续创作!