Cookie和Session
Session 的本质是基于 Cookie 的
Session 是 Web 应用中用于维持用户状态的一种机制。其底层实现通常依赖于 Cookie 技术,通过 JSESSIONID
来标识用户的会话信息。
首次请求时:
当用户首次访问服务器时,Servlet 容器会检查 HTTP 请求中是否包含名为 JSESSIONID
的 Cookie,并查找是否存在与该 ID 对应的 HttpSession
对象。
- 如果是首次访问,且程序中没有调用
getSession()
或getSession(true)
,则不会创建 Session; - 只有当代码中显式调用
getSession()
或getSession(true)
时,容器才会:- 创建一个新的
HttpSession
; - 生成唯一的
JSESSIONID
; - 将该 ID 写入响应头中的
Set-Cookie: JSESSIONID=xxx
,返回给浏览器;
- 创建一个新的
- 浏览器保存该 Cookie 后,在后续请求中将自动携带
JSESSIONID
,用于识别用户会话。
后续请求时:
当用户再次发起请求时,浏览器会自动携带之前保存的 JSESSIONID
(通过 Cookie)发送到服务器。
- Servlet 容器检测到请求中包含
JSESSIONID
,并能查找到对应的HttpSession
; - 此时调用
getSession()
或getSession(true)
会直接返回已有的 Session(不会重新创建新的 Session),除非当前 Session 已失效或过期。
当 Session 被强制失效或自然过期后:
如果 Session 被手动调用 invalidate()
方法销毁,或者因超时而自然过期:
- 用户再次发起请求时,虽然请求中仍携带了
JSESSIONID
; - 但服务器已找不到对应的 Session;
- 此时若调用
getSession()
或getSession(true)
,容器将重新创建一个新的 Session; - 并生成新的
JSESSIONID
返回给客户端,继续后续会话。
特别说明:关于 getSession(false)
getSession(false)
行为不同于其他两个方法;- 如果当前请求没有关联有效的 Session(如首次访问或 Session 已过期),它将返回
null
; - 不会强制创建新的 Session;
- 常用于判断当前用户是否已有有效会话,适用于登录状态检测等场景。
Cookie和Session的区别
存储位置 | 客户端(如浏览器) | 服务器端 |
安全性 | 较低,因为数据存储在客户端,可能被用户篡改或窃取。可以通过设置 HttpOnly 和 Secure 标志提高安全性。 |
较高,因为敏感信息存储在服务器端,不会暴露给客户端。 |
存储容量 | 有限制,通常每个域名下最大4KB左右。 | 可以存储大量数据,受限于服务器的内存或配置的持久化存储空间。 |
传输 | 每次请求都会自动携带相关的Cookie到服务器。 | 只需传递一个短小的 JSESSIONID 到客户端,并通过该ID来关联服务器端的会话数据。 |
生命周期 | 可以通过设置 Max-Age 或 Expires 来控制其生命周期,可以是临时性的也可以是持久化的。 |
生命周期由服务器控制,通常通过设置超时时间来决定会话的有效期。当会话过期或调用 invalidate() 方法时,会话结束。 |
适用场景 | 适合存储少量不敏感的数据,如用户的偏好设置、跟踪访问者等。 | 适合存储需要保护的信息,如登录状态、购物车内容等。 |
隐私问题 | 存储在用户设备上,可能会引起隐私担忧。 | 数据存储在服务器端,减少了对用户隐私的直接暴露。 |
跨域限制 | 受同源策略限制,不同域名下的Cookie不能互相访问。 | 同一应用服务器上的所有Web应用都可以共享同一个Session,不受同源策略限制。 |
性能影响 | 每次请求都会发送Cookie,增加了网络流量和请求大小。 | 减少了每次请求的数据量,但增加了服务器资源的使用。 |
管理复杂度 | 相对简单,主要涉及创建、读取、更新和删除操作。 | 管理相对复杂,涉及到会话的创建、销毁、持久化以及分布式环境下的同步等问题。 |
JavaWeb 文章被收录于专栏
此专栏由于更新观看不便,不会保持及时更新,最新更新见计算机合集专栏https://www.nowcoder.com/creation/manager/columnDetail/04yp33