HTTP协议是无状态的,这里的「状态」到底指什么?
【摘要】 《CS基础 第六篇》
找了很多资料不仅没有发现有一针见血正面回答这个问题的,而且有些解释还充斥了各种错误,看着看着就觉得心里憋着一股浊气吐不出来。于是在看了很多资料之后,大声正面提出这个问题:http协议无状态中的【状态】到底指的是什么?!
然后开始不断探索解决这个问题。。。最终很高兴的是我找到了让人满意的答案,先卖个关子,各位如果着急可以直接拉到最下查看。
正 文
http协议无状态中的【状态】到底指的是什么?!
-
每一个访问都是无连接,服务器挨个处理访问队列里的访问,处理完一个就关闭连接,这事儿就完了,然后处理下一个新的 -
无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接
-
协议对于事务处理没有记忆能力【事物处理】【记忆能力】
-
对同一个url请求没有上下文关系【上下文关系】
-
每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求是无直接关系的,它不会受前面的请求应答情况直接影响,也不会直接影响后面的请求应答情况【无直接联系】【受直接影响】
-
服务器中没有保存客户端的状态,客户端必须每次带上自己的状态去请求服务器【状态】
-
请求内容没有关系只可能是服务器上不存有用户数据才可能啊,但是显然是存有的。 -
请求本身没有关系,这又有什么意义呢,每一次的请求有什么价值?
-
服务器肯定为每个注册用户建立了数据表,记录用户的数据 -
http是无连接的
-
用户通过http把用户的用户名和密码发送给服务器,服务器把他们跟自己存有的用户资料对比,如果一致,则返回信息登录成功。
-
这个动作相当于输入一个商品页的网址 -
假如商品页比较机密不对外公开,需要是用户才能访问 -
而虽然http能传送用户名和密码,而且刚才也输入了,还验证成功了,但是因为服务器既不会记得你登录的状态,你的客户端也不会存储你刚才输入的用户名和密码 -
所以因为这一次访问因为无法确定你的身份,只能访问失败 -
这时候如果要解决这个问题,而且没有cookie没有session,那就只能你在访问网址的同时继续带上你的用户名和密码
-
这个动作也相当于输入一个网址,网址的内容是发送一个请求,往你的购物车中加入这个商品 -
系统首先用你传来的用户名和密码验证你的身份,然后访问你的数据库,在其中的购物车属性下加一条数据,就是这个商品的数据 -
操作结束后,返回操作成功,并结束访问
-
你每访问一次需要权限的内容都需要在客户端输入用户名和密码,这一项的繁琐就不必赘述了
-
你的每一次操作都要与系统底层的数据库进行交互 -
多次少量的访问存在非常大的性能浪费。非常容易就能想到肯定是一次大量的操作更加有效率,于是就想到了缓存区
-
你的非重要琐碎数据也被写进数据库中,跟你的主要数据放在一起 -
一次次添加和删除购物车其实只是跟你这次浏览,或者叫这次会话有关,是临时的数据,跟用户的主要信息无关,它们没什么价值,纯粹的冗余数据(不排除现在有的公司觉得这种数据也有非常大的价值可以让它们巧妙的利用),用什么存放这些临时的数据,我们也很容易想到缓存区
-
服务器上肯定存有用户的数据,你提交的增删改查它也能够处理,所以这句话中【服务器中没有保存客户端的状态】的状态并不是指用户的数据,我们的猜测不对 -
我们的质疑对了,无状态能实现购物车,可以通过服务器上存有的用户数据来实现 -
但是,使用上面这种方式实现购物车,存在三个比较大的问题。由此,我们不禁会想,这三个问题的解决是不是跟我们不确切了解的【状态】一词有关?于是,接下来我们来通过解决这三个问题来把【状态】的意义探寻下去
-
有了这个缓存区作为一个数据缓冲,就不用一次次地访问数据库,浪费大量计算机资源,而是在最后统一归入数据库 -
有了这个缓存区,你就不用把临时的数据放到数据库中了,只需要在你们交流告一段落之后,再把数据整理,把有用的数据归入数据库
-
给每个session一个ID,一方面用来方便自己查询,另一方面把这个ID给用户,用户下一次访问的时候就可以不用用户名和密码,而是直接使用这个ID来表明自己的身份
-
首先,这个ID安全吗?这个ID比直接传用户名和密码安全吗?
-
不严格加密的sessionID和用户名和密码一样,都不太安全 -
但是相比较来说,sessionID要安全一些 -
而使用https是完全安全的
-
方便直接根据ID查询用户对应的session -
加密的时候计算量小 -
安全性不会降低,甚至还更高一些
忽然我想到一个问题:一个有状态的http是什么样的?
-
如果有状态的意思是它的每次请求是有联系的,那么有状态的TCP的样子是:假如一份数据分了三份TCP包发送,那这个包上面会标明这是第几个包,会标明这个包跟那几个包是有联系的,有什么联系
-
只有【每次http请求之间互相有联系】这个条件,无法解决【每一次操作都要与系统底层的数据库进行交互】 -
因为很明显,要解决【每一次操作都要与系统底层的数据库进行交互】就必须在服务器端开辟一块缓存区 -
不过如果你思考一下如何实现【每次http请求之间互相有联系】,你就会发现,它也需要在服务器端开辟一块缓存区 -
所以【在服务器端开辟一块缓存区】才是真正的条件,也就是说,它确实等价于【有状态】 -
而且我也找到了这个【在服务器端开辟一块缓存区】的条件跟前面那些官方对状态的说法对应的点,那就是:
-
通过在服务器端开辟一块缓存区,存储、记忆、共享一些临时数据,你就可以: -
协议对于事务处理有记忆能力【事物处理】【记忆能力】 -
对同一个url请求有上下文关系【上下文关系】 -
每次的请求都是不独立的,它的执行情况和结果与前面的请求和之后的请求是直接关系的【不独立】【直接关系】 -
服务器中保存客户端的状态【状态】
-
所以,这个状态,加上前面说的客户端也有cookie,就是指,客户端和服务器在临时会话中产生的数据!而前面也说道了,使用缓存区保存临时会话中的数据是多么重要
-
所以状态不仅包括不同URL访问之间的关系,还有对其他URL访问的数据记录,还有一些其他的东西,所以更确切地说,状态应该是【实现了这些东西所凭借的后面的缓存空间】中的客户的临时数据 -
cookie和session应该是完全实现了有状态这个功能
一种常见的对状态的误解:
-
有人在解释HTTP的无状态时,把它跟有连接对立,说是两种方式,也就是如果想不无状态,就必须有连接,但其实不然
-
有连接和无连接以及之后的Keep-Alive都是指TCP连接
-
有状态和无状态可以指TCP也可以指HTTP
-
TCP一直有状态,HTTP一直无状态,但是应用为了有状态,就给HTTP加了cookie和session机制,让使用http的应用也能有状态,但http还是无状态
-
开始TCP是有连接,后来TCP无连接,再后来也就是现在TCP是Keep-Alive,有点像有连接。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)