session 原理
session 也是一种记录浏览器状态的机制, 但与 cookie 不同的是, session 是保存在服务器中.
由于 http 是无状态协议, 当服务器存储了多个用户的 session 数据时, 如何确认 http 请求对应服务器上哪一条 session, 相当关键. 这也是 session 原理的核心内容.
解决方法: 服务器向客户端发送一条名为 JESSIONID 的 cookie, 它的值是 session 的 id 值. 通过 JESSIONID 可以识别 http 请求对应哪一个用户. 原理图如下所示:
session 相关应用
与 cookie 共同使用
解决方法: 与 cookie 共同使用. 手动创建名为 JESSIONID 的 cookie, 通过 session.getId() 获取 sessionid, 存入 cookie, 并设置 maxAge.
代码如下:
- Cookie cookie = new Cookie("JSESSIONID",session.getId());
- cookie.setMaxAge(30*60);
- cookie.setPath("/"); // 必须是根路径
- response.addCookie(cookie);
经过实践, 这样做有效. 重启浏览器后, session 依然可用.
防止表单重复提交
业务场景 (重复提交的危害):
在投票的网页上不停地提交, 实现了刷票的效果;
注册多个用户, 不断发帖子, 扰乱正常发帖秩序.
解决方法:
在 session 中存储一个 token, 专业做法是使用随机数或者时间戳;
前端获取得到这个 token, 并将 token 写入表单的隐藏域中;
在第一次提交表单时, 判断 seesion 有没有值, 如果有就比对 token. 对比正确后处理请求, 然后删除 session 中的数据;
再次访问的时, session 是空的, 即避免了重复提交;
一次性验证码
目的: 防止暴力破解密码
实现方法:
初次访问时, 服务端生成随机数, 存入 session 域中, 并生成验证码图片传给前端;
表单填写完毕后, post 请求服务器;
后端读取参数中传递的验证码值, 读取 session 域中的随机数值, 验证两者是否相等.
session 与 cookie 的区别
存储
Cookie 只能存储字符串, 若要存储非 ASCII 字符, 还需要对其编码;
Session 可以存储任何类型数据.
隐私
Cookie 内容对客户端可见;
Session 对客户端不可见.
有效期
Cookie 通过 maxAge 设置有效时间;
Session 通过 maxInactiveInterval 属性设置有效时间; 除此之外, 存储 JESSIONID 的 cookie 有效期与 session 息息相关.
对服务器的负担
Session 是保存在服务器的, 每个用户都会产生一个 Session, 如果是并发访问的用户非常多, 是不能使用 Session 的, Session 会消耗大量的内存;
Cookie 是保存在客户端的. 不占用服务器的资源. 像 baidu,Sina 这样的大型网站, 一般都是使用 Cookie 来进行会话跟踪.
浏览器的支持
浏览器有权选择是否禁用 cookie;
若禁用 cookie,session 可以通过 URL 地址重写来进行会话跟踪.
跨域名上
Cookie 可以通过设置 domain 属性来实现跨域名;
Session 只在当前域名内有效.
本文和上一篇 cookie 博客主要来源与对以下技术博客的学习, 当然不乏自己的思考, 实践和提炼.
Servlet 第五篇 [介绍会话技术, Cookie 的 API, 详解, 应用] https://segmentfault.com/a/1190000013129480
Servlet 第六篇 [Session 介绍, API, 生命周期, 应用, 与 Cookie 区别]
来源: https://www.cnblogs.com/buptleida/p/12312241.html