HTTP無狀態協議,是指協議對於交互性場景沒有記憶能力。html
在點擊一個純的html網頁,請求獲取服務器的html文件資源時,每次http請求都會返回一樣的信息,由於這個是沒有交互的,每一次的請求都是相互獨立的。第一個請求和第二個請求也沒有前後順序,返回處理哪一個,結果都是一樣的資源頁面,由於這種場景是無交互的,不管是什麼人請求這個地址,服務器都是返回那個相同的響應。算法
在無交互場景中上面那樣,固然也不會有太大的問題。可是對於涉及到動態交互的場景,就顯得很尷尬了,何爲交互?有來又有往,對於如出一轍的兩個接口,不一樣的人在請求第二個接口時可能會基於請求第一個接口的結果而有所不一樣。數據庫
如今咱們來想一個複雜的場景,如在購物網站上買一個書包,流程以下:跨域
所謂的登陸只是驗證你是不是一個合法用戶,如果合法則跳轉到信息的頁面,不合法則告知用戶名密碼錯誤。瀏覽器
可是咱們在第一步給服務器發完/login接口後,服務器就忘記了。。。忘記了你這我的,到底有沒有通過認證。安全
因此在添加商品時/cart 你仍是須要將你的帳號密碼和商品信息一塊兒提交給 addCart接口,再讓服務器作驗證。服務器
第三步同理。cookie
因此咱們說涉及到交互時,情形就徹底不同了,由於這三步是有依賴關係的,第一步驗證登陸者是一個合法用戶,驗證經過給你返回200/OK,可是隻要服務器給返回了響應,那麼一個http的請求和響應就結束了。服務器怎麼知道10秒鐘以前你剛剛登陸過呢?很差意思,服務器不知道你有沒有登錄過,他只是對外提供一個登陸接口,要想證實你是合法用戶必須調/login接口。網絡
第二步,將商品加入到購物車中時,你會調用/cart接口,可是注意,這個行爲是和第一步是有關聯關係的,是誰將什麼物品加入到購物車中了?這個誰,有沒有在網站上註冊帳號呢,是否是一個合法用戶呢?因此說在添加購物車的時候,咱們還須要將帳號密碼再次加入到請求參數中,每作一次操做購物車操做時,都須要再把以前已經傳輸過的帳號密碼,再反反覆覆的傳輸一遍又一遍,這是由於服務器不知道你是否是在20秒以前剛登錄過。session
上面的無狀態是指的,無登陸狀態,即服務器不知道某個用戶是否已登陸過了。由於愚蠢的服務器不知道客戶端是否已登陸過了,因此每次都要在交互場景(會話)中請求中帶上上一次的請求信息,如帳號、密碼。明明只須要在/login接口中,才須要對比數據庫中的帳號密碼和客戶端傳的是否一致來肯定合法性。這下在添加購物車中也須要再一次的進行一樣的重複且沒有必要的操做,即下降了響應速度,又對用戶不友好(由於每次都須要填帳號,密碼)。
缺乏狀態意味着若是後續處理須要前面的信息,則它必須重傳,這樣可能致使每次鏈接傳送的數據量增大。另外人們常說的「會話」概念則是上面的交互行爲的另外一種表述方式。
經過上面咱們知道了Http中無狀態是一個什麼概念,以及在無狀態狀況下,要進行添加購物車功能,所帶來的困難。
客戶端與服務器進行動態交互的Web應用程序出現以後,HTTP無狀態的特性嚴重阻礙了這些應用程序的實現,畢竟交互是須要承前啓後的,簡單的購物車程序也要知道用戶到底在以前選擇了什麼商品。因而,兩種用於保持HTTP鏈接狀態的技術就應運而生了,一個是Cookie,而另外一個則是Session。HTTP自己是一個無狀態的鏈接協議,爲了支持客戶端與服務器之間的交互,咱們就須要經過不一樣的技術爲交互存儲狀態,而這些不一樣的技術就是Cookie和Session了。
因爲HTTP是一種無狀態的協議,服務器單純從網絡鏈接上無從知道客戶身份。怎麼辦呢?就給客戶端們頒發一個通行證吧,每人一個,不管誰訪問都必須攜帶本身通行證。這樣服務器就能從通行證上確認客戶身份了。這就是Cookie的工做原理。
Cookie其實是一小段的文本信息。客戶端請求服務器,若是服務器須要記錄該用戶狀態,就使用response向客戶端瀏覽器頒發一個Cookie。客戶端瀏覽器會把Cookie保存起來。當瀏覽器再請求該網站時,瀏覽器把請求的網址連同該Cookie一同提交給服務器。服務器檢查該Cookie,以此來辨認用戶狀態。服務器還能夠根據須要修改Cookie的內容。
不少網站都會使用Cookie。例如,Google會向客戶端頒發Cookie,Baidu也會向客戶端頒發Cookie。那瀏覽器訪問Google會不會也攜帶上Baidu頒發的Cookie呢?或者Google能不能修改Baidu頒發的Cookie呢?
答案是否認的。Cookie具備不可跨域名性。根據Cookie規範,瀏覽器訪問Google只會攜帶Google的Cookie,而不會攜帶Baidu的Cookie。Google也只能操做Google的Cookie,而不能操做Baidu的Cookie。
Cookie在客戶端是由瀏覽器來管理的。瀏覽器可以保證Google只會操做Google的Cookie而不會操做Baidu的Cookie,從而保證用戶的隱私安全。瀏覽器判斷一個網站是否能操做另外一個網站Cookie的依據是域名。Google與Baidu的域名不同,所以Google不能操做Baidu的Cookie。
cookie並非單純爲了實現 session機制而生的。而是1993 年,網景公司僱員 Lou Montulli 爲了讓用戶在訪問某網站時,進一步提升訪問速度,同時也爲了進一步實現我的化網絡,發明了今天普遍使用的 Cookie。cookie還用一個很普遍的用途就是記住用戶的登陸帳號和密碼,這樣當用戶之後再次須要登陸同一個網站或系統的時候就不須要再次填寫這兩個字段而是直接點擊「登陸」按鈕就好。這就至關於給了一些「甜頭」給用戶,這就回應了「cookie」這個詞語的字面意思了。
若是用戶是在本身家的電腦上網,登陸時就能夠記住他的登陸信息,下次訪問時不須要再次登陸,直接訪問便可。
實現方法是把登陸信息如帳號、密碼等保存在Cookie中,並控制Cookie的有效期,下次訪問時再驗證Cookie中的登陸信息便可。
方案一:最直接的是把用戶名與密碼都保持到Cookie中,下次訪問時檢查Cookie中的用戶名與密碼,與數據庫比較。這是一種比較危險的選擇,通常不把密碼等重要信息保存到Cookie中。
方案二:是把密碼加密後保存到Cookie中,下次訪問時解密並與數據庫比較。這種方案略微安全一些。若是不但願保存密碼,還能夠把登陸的時間戳保存到Cookie與數據庫中,到時只驗證用戶名與登陸時間戳就能夠了。
方案三:只在登陸時查詢一次數據庫,之後訪問驗證登陸信息時再也不查詢數據庫。實現方式是把帳號按照必定的規則加密後,連同帳號一塊保存到Cookie中。下次訪問時只須要判斷帳號的加密規則是否正確便可。
一和二兩種方案驗證帳號時都要查詢數據庫。
方案三把帳號保存到名爲account的Cookie中,把帳號連同密鑰用MD5算法加密後保存到名爲ssid的Cookie中。驗證時驗證Cookie中的帳號與密鑰加密後是否與Cookie中的ssid相等。
提示:該加密機制中最重要的部分爲算法與密鑰。因爲MD5算法的不可逆性,即便用戶知道了帳號與加密後的字符串,也不可能解密獲得密鑰。所以,只要保管好密鑰與算法,該機制就是安全的。
因爲網頁是一種無狀態的鏈接程序,所以沒法得知用戶的瀏覽狀態。在網上購物的時,把不少商品加入了購物車,而在結帳時網站殊不知道你購物車有哪些物品。爲了解決這個問題,服務器端就爲特定用戶建立了特定的session,用於標示並跟蹤這個用戶,這樣才知道購物車裏有哪些商品。
Session是另外一種記錄客戶狀態的機制,不一樣的是Cookie保存在客戶端瀏覽器中,而Session保存在服務器上。
客戶端瀏覽器訪問服務器的時候,服務器把客戶端信息以某種形式記錄在服務器上。這就是Session。客戶端瀏覽器再次訪問時只須要從該Session中查找該客戶的狀態就能夠了。
若是說Cookie機制是經過檢查客戶身上的「通行證」來肯定客戶身份的話,那麼Session機制就是經過檢查服務器上的「客戶明細表」來確認客戶身份。
Session至關於程序在服務器上創建的一份客戶檔案,客戶來訪的時候只須要查詢客戶檔案表就能夠了。