浅谈Session,Cookie和http协议中的无状态

首先,Session是记录在服务端的,Cookie是记录在客户端的。

什么是cookie?
Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。Cookie实际上是一小段的文本信息。是客户端保存用户信息的一种机制,用来记录用户的一些信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。它的过期时间可以任意设置,如果你不主动清除它,在很长一段时间里面都可以保留着,即便这之间你把电脑关机了。

什么是Session
Session是在无状态的HTTP协议下,服务端记录用户状态时用于标识具体用户的机制。是一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。它在服务端保存的用来跟踪用户的状态的数据结构,可以保存在文件、数据库或者集群中。在浏览器关闭后这次的Session就消失了,下次打开就不再拥有这个Session。其实并不是Session消失了,而是Session ID变了,服务器端可能还是存着你上次的Session ID及其Session 信息,只是他们是无主状态,一段时间后会被删除。Session存在服务器的 /tmp 目录下。实际上Cookie与Session都是会话的一种方式。

为什么http要搞无状态

首先再说http无状态之前,我想提一下客户端服务端连接的另一种方式-socke连接。socket连接和http连接最大的区别在于socket是长连接,http是短连接。长连接就是客户端服务端某一方如果不主动中断连接,连接是不会被中断的,短连接是当客户端服务端完成信息交互之后,连接会自动关闭。对于为什么http要使用短连接我的理解是这样的:因为http协议是应用于网页里,你浏览网页如果中断浏览,正常人是不会关闭网页的,因此网页会一直阁制,如果此时使用长连接,数据明明传输结束,但是与服务器的连接仍然未关闭,此时便浪费了服务器端的资源,因此使用短连接才是最合理的。

接下来解释什么是无状态协议:

用最简单的话来概括便是:第二次来你无法识别它曾经来过

接下来看一下知乎用户对http无状态的理解:

作者:知乎用户
链接:https://www.zhihu.com/question/23202402/answer/528540607
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

要理解一个技术的特性,一定要知道这个技术出现的历史背景。HTTP协议本来就不是为开发B/S程序而设计的,能够发展到现在并且把C/S打得落花流水,纯属奇葩。

 

HTTP协议最初的目的是用它发布和接收静态的HTML页面,浏览器请求一个网页,服务器就把这个网页传给它,之后就可以断开连接了。在1991年发布的HTTP 0.9里甚至连POST都没有,因为设计者根本就没考虑浏览器还要向服务器提交那么多信息。

同样的,HTTP在设计之初就没有考虑过要保存会话状态。无论你之前访问过什么网页、提交过什么数据,你获得的网页都是一样的;不同的浏览器访问同一个网页所得到的结果也是完全一样的,本来我就是静态网页嘛。这就是所谓的「无状态」——访问URI得到的结果与上下文操作无关、与用户无关

---------------------------------------------------------------------------

然而Web实在太成功了,虽然HTTP无状态的特性使它并不适合用来开发应用程序,却偏偏有人动歪脑筋,生生地往网页里塞标签或者用其他类似的技术让服务器动态生成网页。

但是,应用程序是上下文相关的,你在登录页里输入了uid和pwd登录成功了,在另一个页面中怎么知道你登录成功了呢?这个时候就需要保存「状态」,在这个例子里就是你的登录状态——是否登录成功了、谁登录成功了、什么时候登录成功的。

这些「状态」可以保存在浏览器上,1993年发明的cookie使得HTTP服务器可以通过特殊的指令在浏览器的硬盘上保存一些数据,然后浏览器在每次访问HTTP服务器的时候把这些数据全部提交给服务器。

 

这种方式显而易见会带来问题:

1.每次页面请求都会把cookies往服务器上送一次,浪费了带宽;

2.状态数据存放在浏览器上确实是太危险了,一定会有人想办法把浏览器里的状态信息改掉来欺骗服务器,而且Cookies在HTTP请求中是以明文传输的,除非你用HTTPS。

3.Cookie的大小限制在4KB, 对于复杂的状态数据显然不够用。

 

所以,把所有状态数据都保存在浏览器端是不靠谱的,主流的做法是:

1.浏览器向HTTP服务器发出第一个请求时,服务器分配一个SessionID, 存入浏览器的Cookies中。这个SessionID一般是一个类似于GUID的字符串,几十个字节,也不多。

2. 服务器上维持一个会话状态数据库(也可能是个内存表),用SessionID作为标识存放每一个会话的状态信息。

3. 每一次浏览器发出请求时,都将这个SessionID向服务器提交一次,便于服务器根据它获得之前的会话数据,写入新的会话数据。

这有点类似于医院的医生每天看几十个病人,每当一个病人坐在诊室的时候医生不认识他。怎么办呢?给病人发一个就诊卡,每次看到医生的时候刷一下,医生就可以从后台调出你之前的信息了。

 

当然,普通程序员并不用关心这些过程,你只要学会用Session对象就好了。


session与cookie部分参考于:https://blog.csdn.net/AdminGuan/article/details/100186008

知乎部分参考于:https://www.zhihu.com/question/23202402

posted @ 2021-05-22 22:10  苏州の酱醋茶  阅读(202)  评论(0编辑  收藏  举报