logo头像

总有人间一两风,填我十万八千梦

前端面试系列(7)——session&cookie

本篇文章参考了一些开发者对于 session 和 cookie 的讲解,对这些内容进行了筛选和合并,同时加入了我的理解,争取用最短的篇幅给大家讲清楚这两个概念,因为在前端面试或笔试中会经常碰到这两个问题,同时在很多项目中也会用到

session 的概念

Web 应用程序是使用 HTTP 协议传输数据的。HTTP 协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户 A 购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户 A 的会话还是用户 B 的会话了。要跟踪该会话,必须引入一种机制。
当浏览器第一次发送请求时,服务器自动生成了一个 Session 和一个 Session ID 用来唯一标识这个 Session,并将其通过响应发送到浏览器。当浏览器第二次发送请求,会将前一次服务器响应中的 Session ID 放在请求中一并发送到服务器上,服务器从请求中提取出 Session ID,并和保存的所有 Session ID 进行对比,找到这个用户对应的 Session。一般情况下,服务器会在一定时间内(默认 30 分钟)保存这个 Session,过了时间限制,就会销毁这个 Session。在销毁之前,程序员可以将用户的一些数据以 Key 和 Value 的形式暂时存放在这个 Session 中。当然,也有使用数据库将这个 Session 序列化后保存起来的,这样的好处是没了时间的限制,坏处是随着时间的增加,这个数据库会急速膨胀,特别是访问量增加的时候。一般还是采取前一种方式,以减轻服务器压力。

session 的客户端实现形式

即 session ID 的保存方法,一般浏览器提供了两种方式来保存,还有一种是程序员使用 html 隐藏域的方式自定义实现:

这是最常见的方法,比如“记住我的登录状态”功能的实现正式基于这种方式的。服务器通过设置 Cookie 的方式将 Session ID 发送到浏览器。如果我们不设置这个过期时间,那么这个 Cookie 将不存放在硬盘上,当浏览器关闭的时候,Cookie 就消失了,这个 Session ID 就丢失了。如果我们设置这个时间为若干天之后,那么这个 Cookie 会保存在客户端硬盘中,即使浏览器关闭,这个值仍然存在,下次访问相应网站时,同样会发送到服务器上。

使用 URL 附加信息的方式

也就是像我们经常看到 JSP 网站会有 aaa.jsp?JSESSIONID=* 一样的。这种方式和第一种方式里面不设置 Cookie 过期时间是一样的。

第三种方式是在页面表单里面增加隐藏域

这种方式实际上和第二种方式一样,只不过前者通过 GET 方式发送数据,后者使用 POST 方式发送数据。但是明显后者比较麻烦。

Session 是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的 SessionID,用该 SessionID 为标识符来存取服务器端的 Session 存储空间。而 SessionID 这一数据则是保存到客户端,用 Cookie 保存的,用户提交页面时,会将这一 SessionID 提交到服务器端,来存取 Session 数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用 Cookie,那么 Session 也会失效。服务器也可以通过 URL 重写的方式来传递 SessionID 的值,因此不是完全依赖 Cookie。如果客户端 Cookie 禁用,则服务器可以自动通过重写URL的方式来保存 Session 的值,并且这个过程对程序员透明。可以试一下,即使不写 Cookie,在使用 request.getCookies(); 时取出的 Cookie 数组的长度也是 1,而这个 Cookie 的名字就是 JSESSIONID,还有一个很长的二进制的字符串,是 SessionID 的值。

  • 不可跨域
  • 保存中文只能编码(UTF-8)
  1. 判断用户是否登陆过网站,以便下次登录时能够直接登录。如果我们删除 cookie,则每次登录必须从新填写登录的相关信息。
  2. 另一个重要的应用是“购物车”中类的处理和设计。用户可能在一段时间内在同一家网站的不同页面选择不同的商品,可以将这些信息都写入 cookie,在最后付款时从 cookie 中提取这些信息,当然这里面有了安全和性能问题需要我们考虑了。
  3. 记录用户访问次数,服务器可以通过操作 Cookie 类对象对客户端 Cookie 进行操作
  1. cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
  2. cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗;考虑到安全应当使用session。
  3. session 会在一定时间内保存在服务器的一个文件里(不是内存)。当访问增多,会比较占用你服务器的性能;考虑到减轻服务器性能方面,应当使用 COOKIE。
  4. 单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie。
  5. session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id)
  6. Session 是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中; Cookie 是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现 Session 的一种方式。
  7. 如果说 Cookie 机制是通过检查客户身上的“通行证”来确定客户身份的话,那么 Session 机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session 相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。

参考文章

支付宝打赏 微信打赏

听说赞过就能年薪百万