当前位置: 首页 > 科技观察

N个受访者被难住了,无状态http协议中的“状态”指的是什么?!

时间:2023-03-12 02:01:23 科技观察

印子最近好好了解一下http,发现http介绍的第一句话【http协议是无状态无连接的】看不懂:stateless【state】指的是什么?!查了很多资料,不仅没有找到这个问题的敏锐答案,反而有些解释错误百出。看了之后,觉得自己的心跳不出来。于是看了很多资料,我吐出浑浊的一口气,大声而直接地问了这个问题:http协议stateless中的[state]指的是什么?!然后开始不断探索解决这个问题。..最后,我很高兴我找到了一个满意的答案。让我保守秘密。着急的话可以直接拉到最下面看httpprotocolstateless文本中的[status]指的是什么?!1、再看看这句话的另外两个概念:(标准的http协议是stateless和connectionless)标准的http协议是指不包含cookies、session、applications的http协议。它们不属于Standard协议,虽然各种网络应用提供商、实现语言、Web容器等都默认支持。2.无连接是什么意思?只要关闭连接,事情就结束了,然后处理下一个新的无连接的意思就是限制每个连接只能处理一个请求。服务器处理完客户端的请求并收到客户端的响应后,立即断开连接。对于【无状态】,我看到很多模糊的说法(官方或教程的说法)隔着一层毛玻璃。Veryuncomfortable(butitisactuallytrue)(后来才发现为什么我觉得看起来不舒服,因为他们引入了很多新的,而且很明显是一个宽泛的名词,可能在很多地方都会用到,这些词最大的作用就是,迷惑概念,我在下面标注)协议对事务处理没有记忆能力【事务处理】【记忆能力】同一个url请求没有上下文关系【上下文关系】每个请求都是独立的,它的执行和结果不是与前一个请求和后一个请求直接相关。不会直接影响上一个请求的响应,也不会直接影响后面请求的响应【无直连】【直接影响】服务器中没有保存客户端的状态,客户端必须自带自己的状态每次向服务器请求【状态】,都必须得到准确具体的解释!这几点给了我接下来的思考方向:1.【服务端不保存客户端的状态,客户端每次请求服务端都要带上自己的状态】这里的客户端的状态到底是不是代表服务端不保存客户信息呢?但显然不是。2.【HTTP的无状态特性严重阻碍了这些应用的实现。毕竟,交互需要成为过去和未来之间的纽带。一个简单的购物车程序还需要知道用户之前选择了什么商品】我质疑为什么不能实现无状态的购物车?服务器不能存储任何东西吗?3.【每个请求都是独立的,没有直接关系】我觉得这个说法比较靠谱,但是所谓的differentrequests之间是没有关系的,是说请求的内容没有关系,还是仅仅意味着请求本身没有关系?请求的内容与服务器上没有存储用户数据无关,但显然存在。请求本身与它无关,那有什么意义呢?每个请求的价值是多少?按照这个方向,我做了一个模拟访问实验:如果没有cookie,没有session,只有http,那么当一个注册用户访问这个购物网站的时候,会发生这些事情:1.前提条件:服务器必须提供给用户已经创建了一个数据表来记录用户的数据。HTTP是无连接的。2.第一步是登录,将用户的用户名和密码通过HTTP发送到服务器。服务器将它们与自己存储的用户信息进行比较。如果一致,则返回登录成功的信息3.然后用户点击a产品页面的动作相当于输入产品页面的URL。如果产品页面比较机密,不对外开放,需要用户访问。虽然http可以传输用户名和密码,而且是刚才输入的,验证成功,但是由于服务器不会记住你的登录状态,你的客户端也不会存储你刚才输入的用户名和密码。所以,因为这次无法确定你的身份,只能访问失败。这时候如果要解决这个问题,而没有cookie是没有session的,那么访问网站时只能继续带上用户名和密码(继续输入)。其实就像我现在的APP一样。有时候你会手动输入用户名和密码,现在的情况是:你在购物车里选择了好几件商品,想再添加一件商品,于是点了某件商品旁边的加号。只需输入一个URL。URL的内容是发送将此产品添加到您的购物车的请求。系统首先使用您发送的用户名和密码验证您的身份,然后访问您的数据库。在购物车属性下添加一条数据,即对该商品的数据操作完成后,退货操作成功,访问完成。5.OK,实验结束。好像没有cookie和session,问题就可以解决了。事实上,这两种操作都有很大的问题。您每次访问需要权限的内容时,都需要在客户端输入用户名和密码。这是一个繁琐的项目,所以你不需要细说。每一个操作你都要和系统的底层数据库进行多次交互。访问量小,性能非常高。浪费很容易认为大量的操作一定效率更高,所以我想到你缓存区的不重要和琐碎的数据也会写入数据库,和你的主要数据放在一起添加和一次又一次删除购物车。仅与您的浏览或本次会话有关,属于临时数据,与用户的主要信息无关。它们的价值不大,纯属冗余数据(不排除现在有些公司认为这种数据也有非常大的价值,价值让它们可以巧妙地使用),用什么来存储这些临时数据,我们可以很容易想到缓存区搜索Java知音公众号,回复“后端面试”,本次模拟访问后给大家发Java面试题集,在实验中,结合之前的思考方向,我们知道三点:服务端肯定有用户数据,它也可以处理你提交的增删改查,所以这句话中【服务端不保存客户端状态】的状态是不涉及用户的数据。我们的猜测是错误的,我们的问题是正确的。无状态购物车可以通过存储在服务器上的用户数据来实现。但是用上面的方法实现购物车,有3个比较大的问题。因此,我们不禁要问,这三个问题的解决方案,是不是与我们并不确切知道的“状态”二字有关呢?那么,接下来,我们就通过解决这三个问题来探究【state】的含义。综上所述,我们可以在http的基础上增加一些机制来解决以上三个问题。1.在客户端添加一个记录簿是非常有必要的,就像官方的cookie机制一样,它的用途确实如上面所讨论的,一般用于识别访问者的身份2.在服务器端添加一个缓存区可以解决同时出现的问题最后两个问题有了这个缓存区作为数据缓冲区,就不需要再一次次访问数据库,浪费大量的计算机资源,而是最后统一到数据库中。有了这个缓存区,你就不用把临时数据放到数据库里了,只需要在你的通信结束后,把数据整理一下,把有用的数据放到数据库里。分开,原因不言而喻,它有其独特的重要和不可替代的作用。这个东西刚好和3.1官方加入的session机制是一样的。另外,session的主要作用还有一个很容易混淆和误解的地方:session的值是给访问者分配一个sessionID,而不是用户名和密码。3.2.为什么会很迷惑呢,因为session确实是这么做的,而且也起到了很大的作用,所以说的对,但是只对了一半,而且没有涉及到问题的本质,这种情况是最危险的(貌似非常有说服力,说服了你,所以你很难有继续看下去的动力,但是真实情况和它有偏差,但是偏差不大,所以很难说服你回去,只是隐隐错了,at这个时候你是离真相最近的,也是离真相最远的)3.3.顺便说下为什么对,就是session做的另一个有用的事情:给每个session一个ID,一方面用来方便自己查询,另一方面把这个ID给用户,用户下次访问时可以直接使用这个ID来表明自己的身份,而无需使用用户名和密码。首先,这个ID安全吗?这个ID是不是比直接传递用户名和密码更安全?没有严格加密的sessionID与用户名和密码相同,不是很安全,但是相比之下,sessionID更安全,使用https是完全安全的。1、你很容易认为原来的用户名和密码组合是专门设置的比较复杂,你可以用一组数字代替,是不是太不安全了?2、我们知道http协议本身是完全未加密的。如果使用用户名和密码,第一次访问放在http头中,后面自动保存密码,会放在cookie中。这些根本没有加密。它的安全性基本为0,也就是裸奔,只要被盗,就会丢失3。所以,从这个意义上说,sessionID的安全性与使用用户名密码4没有什么区别。但实际上,虽然http本身是不能加密的,但是有些软件可以在应用层给你手动加密。比如QQ会把用户名密码和临时验证码结合起来,sessionID加上时间戳也是很常用的简单加密方式。5.而且因为sessionID本身是有有效期的,即使丢了,可能很快就过期了,损失可能不会那么大,但是如果用户名和密码丢了,那就是大6了。所以总结是:然后,使用sessionID有什么好处1.直接根据ID查询用户对应的session很方便2.加密时计算量小3.安全性不会降低,甚至更高。OK,通过独立解决纯http机制带来的问题,我们讨论了cookie和session机制的本质,思考:【使用http协议,客户端的状态不会保存在服务端】由加上cookie和session机制就解决了,是不是说明这个[state]和cookie是和session关系很密切的?所以这个stateless指的是【不为本次session设置缓存区,记录本次session的状态,缓存区包括服务器端和用户端】但是貌似关键点还是没断(主要是我感觉和之前的官方身份没有关系,说法不符,甚至没有对应关系)搜索Java知音公众号,回复“后端面试”,送你Java面试题集.突然想到一个问题:有状态的http长什么样子?1、很难直接想象有状态的http是什么样的,因为http的机制天生就是无状态的。2.打个比方。另一种自然状态机制称为TCP。第二个请求是连接的,所以有状态的TCP看起来是这样的:如果一个数据在三个TCP数据包中发送,那么这个数据包会标明是哪个数据包,哪个数据包和哪些数据包有连接,是什么connection3.但是这个statefulTCP好像和我们想要的statefulHTTP没有关系,因为即使每个http请求之间有一个connection,也解决不了上面提到的httpStateless问题4.哎,等等,好像类比:4.1。如果每个http连接都有一个签名,那么在第一次登录成功后,服务端就知道这个签名允许登录,所以后面所有的连接都是同一个签名的http连接才能登录。这里,同一个http之间的master关系使用同一用户发送的连接。这解决了维护登录状态的问题。4.2.同样,尝试用这个【每个http请求相互之间有一个连接】来解决上面遇到的问题【每次操作都要和系统底层数据库进行交互】,但是想了半天,实在是做不到继续。上一期:100道面试题总结4.3.不过我灵机一动,换个角度想了想,好像解决了这个问题:只能解决【每个http请求都互相连接】的条件【每个操作都必须和底层数据库交互】系统]因为很明显要解决[每一个操作都要和系统底层数据库进行交互]的问题,就需要在服务器端开辟一个缓存区。但是如果你想想如何实现【每次http请求之间都有一个连接】,你会发现它还需要在服务器端开一个缓存区,所以【在服务器端开一个缓存区】就是realcondition,也就是说确实等同于[hasState]而且我还发现[在server端开一个缓存区]这个条件对应的是之前官方对state的说法,就是:通过开服务器端的一个缓存区,存储、记忆和共享一些临时数据,你可以:不是独立的,它的执行和结果是跟前面的请求和后面的请求有直接关系【不是独立的】【直接关系】客户端的状态是保存在服务端的【状态】6.所以这个状态,加上客户也有c上面提到的cookies,是指客户端在与服务器的临时会话中产生的数据!前面说过,使用缓存来保存临时会话中的数据是多么重要,所以状态不仅包括不同URL访问之间的关系,还包括其他URL访问的数据记录,以及一些其他的东西,所以更准确的说,state应该是client在【实现这些东西背后的缓存空间】中的临时数据cookie和session,应该完全实现stateful的功能。一个常见的状态误解:有人在解释HTTP时是无状态的,反对有连接。说是有两种方式,就是想要无状态就必须要有连接,其实是没有连接,没有连接和后面的Keep-Alive。Stateful和stateless可以指TCP或HTTP。TCP一直是有状态的,而HTTP一直是无状态的。但是,为了有状态,应用在HTTP中加入了cookie和session机制,这样使用http的应用也可以是有状态的,但是http仍然是无状态的。一开始TCP有连接,后来TCP就没有连接了。后来TCP现在是Keep-Alive,有点像连接。