1. 程式人生 > >HTTP 無狀態協議介紹(以及Cookie、Session)

HTTP 無狀態協議介紹(以及Cookie、Session)

之前一直聽過這個,但是具體含義讓表述又表述不好,所以這次打算整理下。

1.基礎瞭解

HTTP無狀態協議,是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連線傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。

客戶端與伺服器進行動態互動的Web應用程式出現之後,HTTP無狀態的特性嚴重阻礙了這些應用程式的實現,畢竟互動是需要承前啟後的,簡單的購物車程式也要知道使用者到底在之前選擇了什麼商品。於是,兩種用於保持HTTP連線狀態的技術就應運而生了,一個是Cookie,而另一個則是Session。HTTP本身是一個無狀態的連線協議,為了支援客戶端與伺服器之間的互動,我們就需要通過不同的技術為互動儲存狀態,而這些不同的技術就是Cookie和Session了。

2.Cookie 客戶端保持狀態

Cookie是通過客戶端保持狀態的解決方案。從定義上來說,Cookie就是由伺服器發給客戶端的特殊資訊,而這些資訊以文字檔案的方式存放在客戶端,然後客戶端每次向伺服器傳送請求的時候都會帶上這些特殊的資訊。

讓我們說得更具體一些:當用戶使用瀏覽器訪問一個支援Cookie的網站的時候,使用者會提供包括使用者名稱在內的個人資訊並且提交至伺服器;接著,伺服器在向客戶端回傳相應的超文字的同時也會發回這些個人資訊,當然這些資訊並不是存放在HTTP響應體(Response Body)中的,而是存放於HTTP響應頭(Response Header);當客戶端瀏覽器接收到來自伺服器的響應之後,瀏覽器會將這些資訊存放在一個統一的位置,對於Windows作業系統而言,我們可以從: [系統盤]:\Documents and Settings[使用者名稱]\Cookies目錄中找到儲存的Cookie;自此,客戶端再向伺服器傳送請求的時候

,都會把相應的Cookie再次發回至伺服器。而這次,**Cookie資訊則存放在HTTP請求頭(**Request Header)了。

有了Cookie這樣的技術實現,伺服器在接收到來自客戶端瀏覽器的請求之後,就能夠通過分析存放於請求頭的Cookie得到客戶端特有的資訊,從而動態生成與該客戶端相對應的內容。通常,我們可以從很多網站的登入介面中看到“請記住我”這樣的選項,如果你勾選了它之後再登入,那麼在下一次訪問該網站的時候就不需要進行重複而繁瑣的登入動作了,而這個功能就是通過Cookie實現的。

3.Session 伺服器來保持狀態

與Cookie相對的一個解決方案是Session,它是通過伺服器來保持狀態的。

由於Session這個詞彙包含的語義很多,因此需要在這裡明確一下 Session的含義。

首先,我們通常都會把Session翻譯成會話,因此我們可以把客戶端瀏覽器與伺服器之間一系列互動的動作稱為一個 Session。從這個語義出發,我們會提到Session持續的時間,會提到在Session過程中進行了什麼操作等等;
其次,Session指的是伺服器端為客戶端所開闢的儲存空間,在其中儲存的資訊就是用於保持狀態。從這個語義出發,我們則會提到往Session中存放什麼內容,如何根據鍵值從 Session中獲取匹配的內容等。

要使用Session,第一步當然是建立Session了。那麼Session在何時建立呢?當然還是在伺服器端程式執行的過程中建立的,不同語言實現的應用程式有不同建立Session的方法。
在Session被建立之後,就可以呼叫Session相關的方法往Session中增加內容了,而這些內容只會儲存在伺服器中,發到客戶端的只有Session id;客戶端再次傳送請求的時候,會將這個Session id帶上,伺服器接受到請求之後就會依據Session id找到相應的Session,從而再次使用之。正是這樣一個過程,使用者的狀態也就得以保持了。

參考文章:

下面就對http協議中許多概念進行描述,以及之間的關係。

先給出結論:狀態的含義:客戶端域伺服器在某次會話中產生的資料,這些資料存在於快取區中,快取區中儲存、記憶、共享一些臨時資料,從而無狀態就意味著,這些資料不會被保留。

但是

  • 通過增加cookie和session機制,現在的網路請求其實是有狀態的。
  • 在沒有狀態的http協議下,伺服器也一定會保留你每次網路請求對資料的修改,但這跟保留每次訪問的資料是不一樣的,保留的只是會話產生的結果,而沒有保留會話。

標準的HTTP協議是無狀態的,無連線的(具體含義如下):

  • 標準的HTTP協議指的是不包括cookies、session、application的http協議,他們都不屬於標準協議,雖然各種網路提供商,實現語言、web容器等,都預設支援它。
  • 無連線是什麼呢?1.每一個訪問都是無連線,伺服器挨個處理訪問佇列裡的訪問,處理完一個就關閉連線,這事就完了,處理完下一個新的。2.無連線的含義是限制每次連線只處理一個請求。伺服器處理完客戶的請求,並收到客戶的應答後,即斷開連線。

無狀態的官方解釋:

  • 協議對於事務處理沒有記憶能力
  • 對同一個url請求沒有上下文關係
  • 每次的請求都是獨立的,它的執行情況和結果與之前的請求和之後的請求是無直接關係的,它不會受前面的請求應答情況直接影響,也不會直接影響後面的請求應答情況
  • 伺服器中沒有儲存客戶端的狀態,客戶端必須每次帶上自己的狀態去請求伺服器。

但是,上面這些概念引入了很多新的概念,而且有很多廣義名詞,讀起來比較抽象,難於理解。

我們舉個例子來說明問題:假如沒有cookie沒有session,只有http的時候,那當一個註冊使用者訪問網站的時候,會有下面的問題:

  • 你每訪問一次需要許可權的內容都需要在客戶端輸入使用者名稱和密碼,這一項的繁瑣就不必贅述了。
  • 你的每一次操作都要與系統底層的資料庫進行互動(多次少量的訪問存在非常大的效能浪費。非常容易就能想到肯定是一次大量的操作更有效率,於是就想到了快取區)
  • 你的非重要瑣碎資料也被寫進資料庫中,跟你的主要資料放在一起(一次次新增和刪除購物車只是跟你這次瀏覽,或者叫這次會話有關,是臨時的資料,跟使用者的主要資訊無關,它們沒什麼價值,純粹的冗餘資料,用什麼存放這些臨時的資料,我們也很容易想到快取區。)

上面就是無狀態時候,會出現的問題,即使有連線,也無法解決【每一次操作都要與系統底層的資料互動】的問題,要解決【每一次操作都要與系統底層的資料庫進行互動】就必須在服務端開闢一塊快取區。

根據上面的問題,我們可以在http的基礎上增加一些機制來解決上面出現的三個問題:

  • 1.在使用者端增加一個記錄本是非常必要的,正好官方加入的cookie機制跟這個一樣,它的用處也確實是上面討論的那樣,一般就是用來標識訪問者的身份。
  • 2.在伺服器增加一個快取區同時解決後兩個問題(有了這個快取區作為一個數據緩衝,就不用一次次地訪問資料庫,浪費大量計算機資源,而是在最後統一歸入資料庫;2.有了快取區,你就不用把臨時地資料放到資料庫中了,只需要在你們交流一段落之後,再把資料整理,把有用的資料歸入資料庫)
  • 3.這裡就自然引申出一個重要的概念:會話,它作為一個緩衝儲存區被從資料庫中分離出來,理由並不生硬,它有其獨特的重要且不可替代的作用。這個東西恰好跟官方加入的session機制一樣。

附註關於Session ID的知識:

  • 不嚴格加密的Session ID和密碼一樣,都不太安全
  • 但是相比較來說,Session ID要安全一些
  • 而使用https是完全安全的

Session ID的好處:

  • 方便直接根據ID查詢使用者對應的Session
  • 加密的時候計算量小
  • 安全性不會降低,甚至還更高一些

所以,這個狀態就是指,客戶端和伺服器在臨時會話中產生的資料!而前面也說道了,使用快取區儲存臨時會話中的資料是多麼重要,所以狀態不僅包括URL訪問之間的關係,會有對其他URL訪問的資料記錄,還有一些其他的東西,所以更確切地說,狀態應該是【實現了這些東西所憑藉的後面的快取空間】中的客戶的臨時資料。Cookie和Session應該是完全實現了有狀態這個功能。

一種常見的對狀態的誤解:

  • 有人在解釋HTTP的無狀態時,把它跟有連線對立,說是兩種方式,也就是如果想不無狀態,就必須有連線,但其實不然。
  • 有連線和無連線以及之後的Keep-Alive都是指TCP連線。
  • 有狀態和無狀態可以指TCP也可以指HTTP。
  • TCP一直有狀態,HTTP一直無狀態,但是應用為了有狀態,就給HTTP加了Cookie和Session機制,讓使用HTTP的應用也能有狀態,但是HTTP還是無狀態。
  • 開始TCP是有連線,後來TCP無連線,再後來也就是現在TCP是Keep-Alive,有點像有連線。

HTTP協議一共有五大特點:1.支援客戶/伺服器模式;2.簡單快速;3.靈活;4.無連線;5.無狀態。

1.無連線:

無連線的含義:是限制每次連線只處理一個請求。伺服器處理完客戶的請求,並收到客戶的應答後,即斷開連線【即因為每次連線只能處理一個請求,所以無連線就是,不會一直是連線狀態,而不是說,無連線就是傳送完就立馬斷開】。採用這種方式可以節省傳輸時間。

為什麼設定成無連線?因為HTTP的設計者有意利用這種特點將協議設計為請求時建連線、請求完釋放連線,以儘快將資源釋放出來服務其他客戶端。

但是,隨著時間的推移,網頁變得越來越複雜,這時候每次訪問圖片都需要建立TCP連線就顯得很低效。後來,Keep-Alive被提出用來解決這效率低的問題。

Keep-Alive功能使客戶端到服務端的連線持續有效,當出現對伺服器的後繼請求時,Keep-Alive功能避免了建立或重新建立連線。但是,這裡存在另外一個問題:雖然為客戶保留開啟的連線有一定的好處,但它影響了效能,因為在處理暫停期間,本來可以釋放的資源仍舊被佔用。當Web伺服器和應用伺服器在同一臺機器上執行時,Keep-Alive功能對資源利用的影響尤其突出。

這樣一來,客戶端和伺服器之間的HTTP連線就會被保持,不會斷開(超過Keep-Alive規定的時間,意外斷電等情況除外),當客戶端傳送另外一個請求時,就使用這條已經建立的連線。

2.無狀態:

無狀態是指協議對於事務處理沒有記憶能力,伺服器不知道客戶端是什麼狀態。即我們給伺服器傳送 HTTP 請求之後,伺服器根據請求,會給我們傳送資料過來,但是,傳送完,不會記錄任何資訊。

HTTP 是一個無狀態協議,這意味著每個請求都是獨立的,Keep-Alive 沒能改變這個結果。

缺少狀態意味著如果後續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連線傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。

HTTP 協議這種特性有優點也有缺點,優點在於解放了伺服器,每一次請求“點到為止”不會造成不必要連線佔用,缺點在於每次請求會傳輸大量重複的內容資訊。

客戶端與伺服器進行動態互動的 Web 應用程式出現之後,HTTP 無狀態的特性嚴重阻礙了這些應用程式的實現,畢竟互動是需要承前啟後的,簡單的購物車程式也要知道使用者到底在之前選擇了什麼商品。於是,兩種用於保持 HTTP 連線狀態的技術就應運而生了,一個是 Cookie,而另一個則是 Session。

Cookie可以保持登入資訊到使用者下次與伺服器的會話,換句話說,下次訪問同一網站時,使用者會發現不必輸入使用者名稱和密碼就已經登入了(當然,不排除使用者手工刪除Cookie)。而還有一些Cookie在使用者退出會話的時候就被刪除了,這樣可以有效保護個人隱私。

Cookies 最典型的應用是判定註冊使用者是否已經登入網站,使用者可能會得到提示,是否在下一次進入此網站時保留使用者資訊以便簡化登入手續,這些都是 Cookies 的功用。另一個重要應用場合是“購物車”之類處理。使用者可能會在一段時間內在同一家網站的不同頁面中選擇不同的商品,這些資訊都會寫入 Cookies,以便在最後付款時提取資訊。

與 Cookie 相對的一個解決方案是 Session,它是通過伺服器來保持狀態的。

當客戶端訪問伺服器時,伺服器根據需求設定 Session,將會話資訊儲存在伺服器上,同時將標示 Session 的 SessionId 傳遞給客戶端瀏覽器,瀏覽器將這個 SessionId 儲存在記憶體中,我們稱之為無過期時間的 Cookie。瀏覽器關閉後,這個 Cookie 就會被清掉,它不會存在於使用者的 Cookie 臨時檔案。

以後瀏覽器每次請求都會額外加上這個引數值,伺服器會根據這個 SessionId,就能取得客戶端的資料資訊。

如果客戶端瀏覽器意外關閉,伺服器儲存的 Session 資料不是立即釋放,此時資料還會存在,只要我們知道那個 SessionId,就可以繼續通過請求獲得此 Session 的資訊,因為此時後臺的 Session 還存在,當然我們可以設定一個 Session 超時時間,一旦超過規定時間沒有客戶端請求時,伺服器就會清除對應 SessionId 的 Session 資訊。

HTTP協議的主要特點可概括如下:

1.支援客戶/伺服器模式。

2.簡單快速:客戶向伺服器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與伺服器聯絡的型別不同。由於HTTP協議簡單,使得HTTP伺服器的程式規模小,因而通訊速度很快。

3.靈活:HTTP允許傳輸任意型別的資料物件。正在傳輸的型別由Content-Type(Content-Type是HTTP包中用來表示內容型別的標識)加以標記。

4.無連線:無連線的含義是限制每次連線只處理一個請求。伺服器處理完客戶的請求,並收到客戶的應答後,即斷開連線。採用這種方式可以節省傳輸時間。

5.無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連線傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。