-2

由于业务需要,需要手写一个基于内存的session。 众所周知sessionid在浏览器中,只要浏览器不关闭,cookie中的sessionid就会保持不变,但是如果重启浏览器以后sessionid就会发生变化。由于http是无状态请求,后端是如何知道浏览器发生了重启并重新生成sessionid。
请不要说使用内置的方法,我想知道他是如何实现的。

10月29日提问

查看全部 4 个回答

0
  1. 后端未收到Cookie中携带的SID(SessionID)时,后端需要生成SID,然后写入到HTTP头:Set-Cookie:SID=XXX
  2. 浏览器关闭后后端并不会主动通知浏览器已关闭,而是Session自身由于未更新过期时间而失效,失效后即使浏览器Cookie携带SID,后端也会认为无效
  3. 如果需要知道浏览器发生了重启,可以在浏览器页面启动时写入本次启动时间和上次启动时间,这样可以判断是否重启过

推荐答案

6

众所周知 开始后面就都是错的,你根本就不知道什么是 Session。

HTTP 是无状态的,服务端收到两个请求时,它并不能知道这两个请求之间有什么关系(比如是否是由同一个客户端发出,这也是最重要的)。

为了解决这个问题,浏览器引入了 Cookie 了机制,即首次请求服务端后,由服务端返回一个 Set-Cookie 响应标头,浏览器收到后会自动存储(也可以是接口形式返回,前端由 JS 来操作写入 Cookie);下次给发送同域请求时,会在请求标头中携带刚才存储的值。服务端收到 Cookie 后就可以依此判断这个请求由谁发出的了。

这么做有两个弊端。一是 Cookie 携带的信息过多的话,影响带宽;二是 HTTP 几乎是明文传输的,Cookie 中如果有敏感信息的话容易被窃取或篡改。那么能不能 Cookie 只发送一个 固定的编号,而这个编号所代表的真实 Cookie 信息只存储在服务端上?因此引入了 Session。

所以说,Session 是 Cookie 的子集,二者是被包含和包含的关系。

在 Cookie 中,服务端需要知道浏览器是否重启了吗?不需要。它只知道某个请求带没带 Cookie、带的这个 Cookie 是不是有效的。如果没带,那么这个请求对于服务端来说就是首次请求。

那么作为 Cookie 子集的 Session,它需要吗?答案不言而喻。


P.S. Cookie 的提出只是为了缓解 HTTP 无状态的问题,除此之外还有其他方案可以实现。比如每个请求携带固定的查询字符串、或者是添加 Authorization 请求标头(如 JWT)等等。只不过 Cookie 是浏览器天然支持而已。

推广链接