session的运行机制

Session 如何实现

session的两种实现方式(也就是传递方式):第一种通过cookies实现。第二种通过URL重写来实现

一、通过cookies实现

把session的id 放在cookie里面(为什么是使用cookies存放呢,因为cookie有临时的,也有定时的,临时的就是当前浏览器什么时候关掉即消失,也就是说session本来就是当浏览器关闭即消失的,所以可以用临时的cookie存放。保存再cookie里的sessionID一定不会重复,因为是独一无二的。),当允许浏览器使用cookie的时候,session就会依赖于cookies,当浏览器不支持cookie后,就可以通过第二种方式获取session内存中的数据资源。

二、通过URL重写来实现

在客户端不支持cookie的情况下使用。为了以防万一,也可以同时使用。

如果不支持cookie,必须自己编程使用URL重写的方式实现。

如何重写URL:通过response.encodeURL()方法

encodeURL()的两个作用

第一个作用:转码(说明:转中文的编码,或者一些其他特殊的编码。就好比如网页的链接中存在中文字符,就会转换成为一些百分号或者其他的符号代替。)

第二个作用:URL后面加入sessionID,当不支持cookie的时候,可以使用encodeURL()方法,encodeUTL()后面跟上sessionID,这样的话,在禁用cookie的浏览器中同时也可以使用session了。但是需要自己编程,只要链接支持,想用session就必须加上encodeURL()。

提示:若想程序中永远支持session,那就必须加上encodeURL(),当别人禁用了cookie,一样可以使用session。

 

大多数 Web 框架都提供了操作 Session 的 API。 如果你有 Web 端开发的经验,那么你对这样的代码应该不会陌生:
session["name"] = "xxx";
我们给 session 对象设置一个值,比如用户登录成功后,给他设置一个用户名,这样我们这个用户的状态就保存下来了。 并且后续的请求中,这个状态都可以读取到。这一切就这么自动的发生了,并且习以为常。那么这一行代码背后发生了什么呢? 就是下面几个步骤。

生成 Session ID

关于 Session 的工作原理, 其实还是值得我们了解一下的。 我们调用上面这行代码后,我们使用的 Web 框架首先会给当前请求创建一个 Session ID。 这个 Session ID 是通过一系列算法生成的一个唯一字符串。 这也是一个 Web 框架(PHP, Ruby on Rails, ExpressJS 等)提供的基础能力,每个框架生成 Sesssion ID 的具体实现算法可能有所差别,但整体流程都是一样的。

 

问题:如何知道浏览器和这个服务器中的session是一一对应的呢?又如何保证不会去访问其它的session呢?

原理解答:就是当访问一个页面的时候给浏览器创建一个独一无二的号码,也给同时创建的session赋予同样的号码。这样就可以在打开同一个网站的第二个页面时获取到第一个页面中session保留下来的对应信息(理解:当访问第二个页面时将号码同时传递到第二个页面。找到对应的session。)。这个号码也叫sessionID,session的ID号码,session的独一无二号码。
 

建立服务端 Session 存储结构

这个新生成的 Session ID 用于标识这次发起请求的用户,并存储到服务器的某个区域中(默认情况下会在内存中)。 这个 Session ID 同样也是本地存储的一个 key,比如我们上面代码中设置了 name 属性,就相当于在这个 key 中设置了对应的属性。 这样说起来可能有点抽象,举个例子 Session 在服务端的存储结构大概相当于这样:
{ "session-id-1": { "name" : "xxx" }, "session-id-2": { "name" : "xxx" } //... } }
服务端会保存这样一个字典, 将每个用户的 Session ID 和对应的属性都记录下来。

把 Session ID 返回给用户浏览器

还继续我们刚才的流程,生成完 Session ID 并建立好本地存储结构后, 服务端会在返回给用户的 HTTP 响应消息中带上这个 Session ID:

 

 

如上图, 通过 Response Header 的 set-cookie 带上,这样截图使用的是基于 Express 的 NodeJS 服务端框架, 这里面的 connect.sid=xxx 就是服务端给这个用户生成的 Session ID。
这样,用户的浏览器得到这个 Cookie 后,再下一次请求同一个网站的时候就会在请求中带上这个 Cookie。
如果你对 Cookie 的细节不熟悉的话,不用多想,你可以理解成这样 — 你用的所有浏览器都会有这个逻辑,收到 set-cookie 响应头后,就会把里面的内容保存下来,下一次再访问同样的站点时候,就会把之前保存的 cookie 再重新发送回去。当然,关于 Cookie 的细节还有很多知识,不过理解我的这个简单解释就足够了,感兴趣的话可以再深入研究。

客户端发送 Session ID

就会像我们刚说的,浏览器下一次再请求这个网站时,会把之前保存的 Session ID 再重新发给服务端。 这时候服务端就会用这个 Session ID 和它之前建立的存储结构中进行匹配,如果这个 Session ID 是之前合法创建的,那么就可以从服务端存储中得到用户之前的状态了,比如登录用户名之类的。 比如:
{ //... "session-id-1": { "name" : "xxx" } //... }
假设上面是我们服务端建立的本地 Session 数据存储,如果 Session ID 正确匹配,就能找到对应这个用户的 name 属性了。

整体步骤

上面给大家介绍的就是 Session 整体的工作过程。 大概分为这几个步骤:

浏览器第一次请求网站, 服务端生成 Session ID。
把生成的 Session ID 保存到服务端存储中。
把生成的 Session ID 返回给浏览器,通过 set-cookie。
浏览器收到 Session ID, 在下一次发送请求时就会带上这个 Session ID。
服务端收到浏览器发来的 Session ID,从 Session 存储中找到用户状态数据,会话建立。
此后的请求都会交换这个 Session ID,进行有状态的会话。


链接:

https://www.jianshu.com/p/a1be3e16ecf6

https://blog.youkuaiyun.com/weixin_42217767/article/details/92760353

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值