面试官问:Http请求中如何保持状态?

共 3158字,需浏览 7分钟

 ·

2020-08-16 06:11




微信搜一搜
架构师修行之路

这是一个被无数程序员撸过的问题,却只有少数人了解了真相。大体上搜了一下,网上关于http协议保持状态误导大家的文章还是有的,比如:有人说利用ViewState,那是asp.net下独有的东西,请注明“asp.net下如何保持状态”!!


关于用户认证方案可以查看以前的文章:

程序员过关斩将--cookie和session的关系其实很简单

程序员过关斩将--互联网人必备知识cookie和session认证

程序员过关斩将--更加优雅的Token认证方式JWT


01
PART
Http协议

http协议相对我们的年龄来说,是一个比较古老的协议,它的诞生之初是为了能让人们在互联网的领域自由冲浪。到了现代,http协议不谦虚的讲,已经成为了分布式网络的基础之一,从最初的1.0版本到现在的2.0乃至研发中的3.0,它在分布式通信领域已经越来越重要。


无论http协议什么样的文章,都需要把http大体说上一下,这里就简单啰嗦几句

http协议在报文的编码方式上采用了文本方式,通信上采用客户端到服务器的请求-响应方式。


http协议是基于tcp协议之上的应用层协议,所以它的传输速度注定会收到tcp协议的约束。有人说http协议采用文本协议是一个天大的错误,我不这么认为,首先在http协议被发明之初,可供的选择并不多,在当时看来,文本协议已经是比较好的选择了。其次,文本协议除了在传输性能上比二进制方式差一些,其他都还好,尤其是在数据的直观性上,很容易被我们理解。尤其是程序员,在看到http的请求和返回文本内容的时候,就可以大体猜出很多东西。


在我看来,http最大的缺陷在于交互中的设计,换句话说,http的状态保持问题,才是在我们平时开发中面临的最大问题。http天生是无状态的,但这并不意味着不能解决。


为什么我们要保持状态呢?根本原因在于现在的互联网的交互需求。什么是保持状态呢?通俗来讲,客户端发起的http请求,服务端需要知道来自于哪个客户端。设想,如果没有状态,当你逛淘宝的时候,剁手下了单,服务器怎么知道是你下的单呢?如果把你的单发给别人,你是不是要去骂娘了呢?

说到http保持状态,我有一点要声明,http和浏览器是有区别的,浏览器只不过是利用http协议来进行通信,有不少同学一提到http协议,就以浏览器来举例,这个是不健全的


http协议要想保持状态,无非就是利用http协议本身定义的那些属性来实现。比如:Header,Body ......只要服务器能识别,理论上就可以作为保持状态的凭据


02
PART
参数保持状态

http保持状态最简单并且最粗暴的莫过于直接采用参数了。服务器把参数凭据通过http协议下发给客户端,客户端无论存储到哪,只要下次请求把这个参数携带上,服务器就可以根据约定读取相应的参数来进行识别。


这种方式目前大多数用来保持那些非敏感信息,比如最常见的分页参数

https://www.cnblogs.com/#p2

有人会有疑问?分页参数也算是状态吗?虽然大多数的文章中所说的状态是指用户的登录状态,但是从状态的抽象定义上来看,分页也算是一种状态的定义。而用户身份状态的保持,由于涉及到隐私,一般不会采用url参数的方式来维持。


03
PART
Cookie保持状态

Cookie是http请求中header中的一个属性,它保存在客户端。

很多文章里,都说Cookie是服务端下发给客户端的,你们这样说是不是不太好?Cookie本质是上客户端的东西,客户端不能自己创建Cookie吗?客户端当然可以自己创建Cookie!!只不过在用户进行认证的流程中,标识用户身份的cookie是服务器下发的,所以在介绍Cookie本身定义的时候请不要误导别人。


利用Cookie来保持http的状态是现在很常见的解决方案,其中的一个原因是:在浏览器中没有跨域的情况下,浏览器会在http请求中自动携带cookie,非常方便。在非浏览器环境中,可能需要写代码来保证每次都携带对应的cookie。


服务端在接收到http请求,解析对应的cookie即可得到需要保持的状态标识。说到服务端,不少人提到了session会保持http状态,这是不是又不太好了,首先session本质上是一个抽象的概念,其次我们平时所说的用户信息等session是属于服务端的kv数据,不同的客户端可以识别不同的session本质上也是通过cookie机制来实现,我认为那些说session可以保持http状态的说法是不明确的。


04
PART
还有其他吗?

除了以上两种方式还有其他方式可以保持http的请求状态吗?当然有!!


http状态的保持需要客户端和服务端同时协作来保证,如果客户端上传了cookie,但是服务端不能正常解析,这也算不上状态的保持。理论上服务端只要能识别http请求中携带的某些数据,就能达到保持状态的目的。


在浏览器中,受限于每个浏览器的功能,浏览器发送一个http请求,自动携带的只有规定的那些header和body数据,而多数header只能携带协议规定的那些固定值,这也是浏览器中要想保持http状态方案少的原因之一。body一般用在post的http请求中,所以它的应用场景是有限的。


关于http的header的属性有很多,有兴趣的同学可以去研究一下。这里提及一个“Authorization”,从字面意思就可以知道它和认证相关,当我们要保持http请求中用户的登录状态时候可以用此字段。那保持其他状态是否可以用呢?当然可以,header中的那些值本质上对于服务端来说就是kv数据,这些数据用于什么用途,每个业务都可以灵活控制。比如:通常情况下,“Authorization”这个header用于用户认证,那我可不可以用于识别是A页面还是B页面呢,当然可以,只要客户端在不同的页面上传不同的“Authorization”值,然后服务端去识别这些值就可以了。


从来没有人说过http协议只能用于客户端和服务端。服务端和服务端通信同样能够使用http协议,而且现在很多分布式系统都是这样来通信的。至于服务端和服务端通信,那http协议保持状态就更加灵活了(这里针对浏览器来比较),请求方和接受方可以约定任意的header头来标识状态,这还要得益于http协议header头可以自定义的特性。比如:如果喜欢“XXOO”,完全可以采用“XXOO”的header来标识状态

Accept: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: 
.
.
.
XXOO:10次/天

05
PART
写在最后

每个问题的解决方案有很多,没有完美的方案,只有最适合业务场景的方案。认清技术的本质,才是我们提高自身技能的捷径。能力有限,技术无限,欢迎批评指正!


往期推荐

为什么不能在代码中使用「User」这个单词?
2020年8月程序员工资统计,下跌势头终于停止了!
卧槽,又来一个神奇的网站!
回复 【关闭】广
回复 【实战】获取20套实战源码
回复 【福利】获取最新微信支付有奖励
回复 【被删】
回复 【访客】访
回复 【卡通】学制作微信卡通头像
回复 【python】学微获取全套0基础Python知识手册
回复 【2019】获取2019 .NET 开发者峰会资料PPT
浏览 40
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报