本文主要介绍“无状态http协议中的‘状态’是什么意思”。在日常操作中,相信很多人对于无状态http协议中的‘state’是什么意思都有疑问。边肖查阅了各种资料,整理出简单易用的操作方法,希望能帮助大家解决“无状态http协议中‘state’是什么意思”的疑惑。接下来,请和边肖一起学习!
http无状态中的[state]到底指的是什么?
1.先看这句话中的另外两个概念:(标准http协议是无状态和无连接的)标准http协议指的是不包含cookies、session和application的http协议,它们不是标准协议,尽管各种网络应用程序提供者、实现语言和web容器都默认支持它。
无连接指的是什么
每次访问都是无连接的。服务器逐个处理访问队列中的访问,处理完一个后关闭连接,然后处理下一个。
无连接意味着每个连接只限于一个请求。服务器处理完客户的请求并收到客户的回复后,就会断开连接。
至于无状态,我看到很多模糊的语录(官方或教程语录)被一层磨砂玻璃隔开,看着很不舒服(但其实是正确的)(后来我发现为什么看着会觉得不舒服,因为它们引入了很多新的、显然是一个广义的名词,可能在很多地方都会用到。这些词最大的作用是混淆概念,我在下面做了标记)。
协议没有事务处理的内存能力[事务处理][内存能力]。
同一url请求没有上下文。
每个请求都是独立的,其执行和结果与前一个请求和后一个请求没有直接关系,不会直接受到前一个请求响应的影响,也不会直接影响后一个请求响应[没有直接关系][直接影响]。
客户端的状态没有保存在服务器中,所以客户端每次都必须自带状态向服务器请求【状态】。
我必须得到一个确切具体的解释!
这几点给了我下一步思考的方向:
1.【客户端的状态没有保存在服务器中,客户端每次都要自带状态向服务器请求】这里的客户端状态是否确切的表示服务器没有保存客户端的信息?但显然不是。
2.HTTP的无状态性质严重阻碍了这些应用程序的实现。毕竟交互需要是连接过去和未来的纽带,一个简单的购物车程序需要知道用户之前选择了什么产品】我质疑为什么购物车没有无状态就无法实现。服务器不能存储任何东西吗?
3.【每个请求都是独立的,其执行和结果与前一个请求和后一个请求没有直接关系】我觉得这个说法比较靠谱,但所谓不同请求之间没有关系,是说请求的内容与它无关,还是只是说请求本身与它无关?
请求与内容无关。只有可能服务器上没有用户数据,但显然是有的。
请求本身与此无关。有什么意义?每个请求的价值是什么?
按照这个方向,我做了一个模拟访问实验:如果没有cookie,没有session,只有http,那么当一个注册用户访问这个购物网站的时候,就会发生这些事情:
1.前提情况:
服务器必须为每个注册用户建立一个数据表来记录用户的数据。
Http无连接。
2.第一步需要登录
用户通过http将用户的用户名和密码发送到服务器,服务器将它们与存储的用户数据进行比较。如果它们一致,它将返回登录成功的信息。
3.然后用户点击某一商品页
此操作相当于输入产品页面的网址。
如果产品页面是保密的,不对公众开放,则需要用户访问。
虽然http可以传输用户名和密码,而且是刚才输入的,认证成功,因为服务器不会记住你的登录状态,你的客户端也不会存储你刚才输入的用户名和密码。
因此,这次访问失败,因为无法确定您的身份。
这个时候,如果你想解决这个问题,又没有cookie又没有会话,那就只能。
你在访问网址的同时继续带上你的用户名和密码(继续输入咯)其实就像我现在的APP一样
4.假设上一步的问题解决了,就是每次访问的时候都会手动输入用户名和密码,然后现在的情况是:你已经选了几件商品在你的购物车中,你想再添加一件商品,于是你点击某个商品旁边的加号
-
这个动作也相当于输入一个网址,网址的内容是发送一个请求,往你的购物车中加入这个商品
-
系统首先用你传来的用户名和密码验证你的身份,然后访问你的数据库,在其中的购物车属性下加一条数据,就是这个商品的数据
-
操作结束后,返回操作成功,并结束访问
5.OK,实验结束,看似没有cookie没有session也能凑合解决问题,其实两个操作都有很大的问题
-
你每访问一次需要权限的内容都需要在客户端输入用户名和密码,这一项的繁琐就不必赘述了
-
你的每一次操作都要与系统底层的数据库进行交互
-
多次少量的访问存在非常大的性能浪费。非常容易就能想到肯定是一次大量的操作更加有效率,于是就想到了缓存区
-
你的非重要琐碎数据也被写进数据库中,跟你的主要数据放在一起
-
一次次添加和删除购物车其实只是跟你这次浏览,或者叫这次会话有关,是临时的数据,跟用户的主要信息无关,它们没什么价值,纯粹的冗余数据(不排除现在有的公司觉得这种数据也有非常大的价值可以让它们巧妙的利用),用什么存放这些临时的数据,我们也很容易想到缓存区
搜索Java知音公众号,回复“后端面试”,送你一份Java面试题宝典
经过这个模拟访问实验,结合前面的思考方向,我们知道了三点:
-
服务器上肯定存有用户的数据,你提交的增删改查它也能够处理,所以这句话中【服务器中没有保存客户端的状态】的状态并不是指用户的数据,我们的猜测不对
-
我们的质疑对了,无状态能实现购物车,可以通过服务器上存有的用户数据来实现
-
但是,使用上面这种方式实现购物车,存在三个比较大的问题。由此,我们不禁会想,这三个问题的解决是不是跟我们不确切了解的【状态】一词有关?于是,接下来我们来通过解决这三个问题来把【状态】的意义探寻下去
由上所述,我们可以在http的基础上增加一些机制来解决上面出现的三个问题
1.在用户端增加一个记录本是非常有必要的,正好官方加入的cookie机制跟这个一样,它的用处也确实是上面讨论的那样,一般就是用来标识访问者的身份
2.在服务器增加一个缓存区能同时解决后两个问题
-
有了这个缓存区作为一个数据缓冲,就不用一次次地访问数据库,浪费大量计算机资源,而是在最后统一归入数据库
-
有了这个缓存区,你就不用把临时的数据放到数据库中了,只需要在你们交流告一段落之后,再把数据整理,把有用的数据归入数据库
3.这里就自然引申出了一个重要的概念:会话,它作为一个缓冲存储区被从数据库中分离出来,理由并不生硬,它有其独特的重要且不可替代的作用。这个东西恰好跟官方加入的session机制一样
3.1.另外说一个非常具有迷惑性的容易让人对session的主要作用产生偏离的理解:认为session存在的价值就是给访问者分配一个sessionID代替用户名和密码,
3.2.为什么非常具有迷惑性,因为session确实做了这件事,而且也起到了很大的作用,所以它是对的,但是只对一半,而且没有涉及问题的本质,这种情况是最危险的(看似很有说服力,把你说服了,所以你很难有动力继续找下去,但是真实情况跟它有偏差,但是偏差不大,所以又很难把你说服回来,只有隐隐的不对劲,这个时候你离真实最近,也离真实最远)
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机制解决了,是不是就意味着这个【状态】跟cookie和session的关系非常紧密?
所以这个无状态指的是【没有对 本次会话 设置一个缓存区,记录这次会话的状态,缓存区包括服务器端和用户端】但好像还是没有点破关键(主要是觉得跟前面那些官方对状态的说法不太吻合,甚至没有对应关系)
搜索Java知音公众号,回复“后端面试”,送你一份Java面试题宝典
忽然我想到一个问题:一个有状态的http是什么样的?
1.很难直接想象有状态的http是什么样,因为http这种机制是天然无状态的
2.那就类比一下吧,另一个天然有状态的机制叫TCP
-
如果有状态的意思是它的每次请求是有联系的,那么有状态的TCP的样子是:假如一份数据分了三份TCP包发送,那这个包上面会标明这是第几个包,会标明这个包跟那几个包是有联系的,有什么联系
3.但好像这个有状态的TCP跟我们想要的有状态的HTTP没有关系,因为即使每次http请求之间互相有联系,它也不能解决上面提到的http无状态的问题
4.诶,等等,好像能类比:
4.1.假如每个http连接都有一个签名,于是第一次登陆成功之后,服务器就知道了这个签名是允许登陆的,于是之后所有同样签名的http连接都能登陆,这里利用了同一个用户发出的http连接之间的同主人关系,这里解决了一个保持登录状态的问题
4.2.同样,来尝试利用这个【每次http请求之间互相有联系】来解决上面碰到的那个问题【每一次操作都要与系统底层的数据库进行交互】,但想了半天确实无法进行下去。往期:一百期面试题汇总
4.3.不过我灵机一动,从另一个角度来想,好像解决了这个问题:
-
鸿蒙官方战略合作共建——HarmonyOS技术社区
-
只有【每次http请求之间互相有联系】这个条件,无法解决【每一次操作都要与系统底层的数据库进行交互】
-
因为很明显,要解决【每一次操作都要与系统底层的数据库进行交互】就必须在服务器端开辟一块缓存区
-
不过如果你思考一下如何实现【每次http请求之间互相有联系】,你就会发现,它也需要在服务器端开辟一块缓存区
-
所以【在服务器端开辟一块缓存区】才是真正的条件,也就是说,它确实等价于【有状态】
-
而且我也找到了这个【在服务器端开辟一块缓存区】的条件跟前面那些官方对状态的说法对应的点,那就是:
-
通过在服务器端开辟一块缓存区,存储、记忆、共享一些临时数据,你就可以:
-
协议对于事务处理有记忆能力【事物处理】【记忆能力】
-
对同一个url请求有上下文关系【上下文关系】
-
每次的请求都是不独立的,它的执行情况和结果与前面的请求和之后的请求是直接关系的【不独立】【直接关系】
-
服务器中保存客户端的状态【状态】
6. 所以,这个状态,加上前面说的客户端也有cookie,就是指,客户端和服务器在临时会话中产生的数据!而前面也说道了,使用缓存区保存临时会话中的数据是多么重要
-
所以状态不仅包括不同URL访问之间的关系,还有对其他URL访问的数据记录,还有一些其他的东西,所以更确切地说,状态应该是【实现了这些东西所凭借的后面的缓存空间】中的客户的临时数据
-
cookie和session应该是完全实现了有状态这个功能
一种常见的对状态的误解:
-
有人在解释HTTP的无状态时,把它跟有连接对立,说是两种方式,也就是如果想不无状态,就必须有连接,但其实不然
-
有连接和无连接以及之后的Keep-Alive都是指TCP连接
-
有状态和无状态可以指TCP也可以指HTTP
-
TCP一直有状态,HTTP一直无状态,但是应用为了有状态,就给HTTP加了cookie和session机制,让使用http的应用也能有状态,但http还是无状态
-
开始TCP是有连接,后来TCP无连接,再后来也就是现在TCP是Keep-Alive,有点像有连接
到此,关于“http协议无状态中的 "状态" 指的是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/42842.html