程序员过关斩将--Http请求中如何保持状态?
微信搜一搜
架構師修行之路
這是一個被無數程序員擼過的問題,卻只有少數人了解了真相。大體上搜了一下,網上關于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
寫在最后
每個問題的解決方案有很多,沒有完美的方案,只有最適合業務場景的方案。認清技術的本質,才是我們提高自身技能的捷徑。能力有限,技術無限,歡迎批評指正!
●程序員修神之路--為什么我會了SOA,你們還要逼我學微服務?
●程序員過關斬將--數據庫的樂觀鎖和悲觀鎖并非真實的鎖
●程序員修神之路--設計一套RPC框架并非易事
●程序員過關斬將--要想獲取我的用戶信息,就得按照規矩來
●程序員過關斬將--更加優雅的Token認證方式JWT
●程序員過關斬將--cookie和session的關系其實很簡單
●程序員修神之路--用NOSql給高并發系統加速
●程序員修神之路--高并發系統設計負載均衡架構
●程序員過關斬將--你為什么還在用存儲過程?
●程序員修神之路--問世間異步為何物?
●程序員修神之路--提高網站的吞吐
總結
以上是生活随笔為你收集整理的程序员过关斩将--Http请求中如何保持状态?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腾讯招.NET,居然要求精通MySQL,
- 下一篇: 基于C#开发的浏览器隐身工具-上班别乱开