天天看點

淺談http的無狀态性

    http是hyper text transfer protocol的縮寫,顧名思義,這個協定支援着超文本的傳輸。那麼什麼是超文本呢?說白了就是使用html編寫的頁面。通常,我們使用用戶端浏覽器通路伺服器的資源,最常見的url也是以html為字尾的檔案。是以,我們可以說超文本是網絡上最主要的資源。

        既然http協定的目的在于支援超文本的傳輸,更加廣義一些就是支援資源的傳輸,那麼在用戶端浏覽器向http伺服器發送請求,繼而http伺服器将相應的資源發回給用戶端這樣一個過程中,無論對于用戶端還是伺服器,都沒有必要記錄這個過程,因為每一次請求和響應都是相對獨立的,就好像你在自動售貨機前投下硬币購買商品一樣,誰都不會也不需要記住這樣一個交易過程。一般而言,一個url對應着唯一的超文本,而http伺服器也絕對公平公正,不管你是michael,還是jordon,它都會根據接收到的url請求傳回相同的超文本。正是因為這樣的唯一性,使得記錄使用者的行為狀态變得毫無意義,是以,http協定被設計為無狀态的連接配接協定符合它本身的需求。

        然而,随着時間的推移,人們發現靜态的html着實無聊而乏味,增加動态生成的内容才會令web應用程式變得更加有用。于是乎,html的文法在不斷膨脹,其中最重要的是增加了表單(form);用戶端也增加了諸如腳本處理、dom處理等功能;對于伺服器,則相應的出現了cgi(common gateway interface)以處理包含表單送出在内的動态請求。在這種用戶端與伺服器進行動态互動的web應用程式出現之後,http無狀态的特性嚴重阻礙了這些應用程式的實作,畢竟互動是需要承前啟後的,簡單的購物車程式也要知道使用者到底在之前選擇了什麼商品。于是,兩種用于保持http連接配接狀态的技術就應運而生了,一個是cookie,而另一個則是session。

        cookie是通過用戶端保持狀态的解決方案。從定義上來說,cookie就是由伺服器發給用戶端的特殊資訊,而這些資訊以文本檔案的方式存放在用戶端,然後用戶端每次向伺服器發送請求的時候都會帶上這些特殊的資訊。讓我們說得更具體一些:當使用者使用浏覽器通路一個支援cookie的網站的時候,使用者會提供包括使用者名在内的個人資訊并且送出至伺服器;接着,伺服器在向用戶端回傳相應的超文本的同時也會發回這些個人資訊,當然這些資訊并不是存放在http響應體(response body)中的,而是存放于http響應頭(response header);當用戶端浏覽器接收到來自伺服器的響應之後,浏覽器會将這些資訊存放在一個統一的位置,對于windows作業系統而言,我們可以從:[系統盤]:\documents and settings\[使用者名]\cookies目錄中找到存儲的cookie;自此,用戶端再向伺服器發送請求的時候,都會把相應的cookie再次發回至伺服器。而這次,cookie資訊則存放在http請求頭(request header)了。

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

        與cookie相對的一個解決方案是session,它是通過伺服器來保持狀态的。由于session這個詞彙包含的語義很多,是以需要在這裡明确一下session的含義。首先,我們通常都會把session翻譯成會話,是以我們可以把用戶端浏覽器與伺服器之間一系列互動的動作稱為一個session。從這個語義出發,我們會提到session持續的時間,會提到在session過程中進行了什麼操作等等;其次,session指的是伺服器端為用戶端所開辟的存儲空間,在其中儲存的資訊就是用于保持狀态。從這個語義出發,我們則會提到往session中存放什麼内容,如何根據鍵值從session中擷取比對的内容等。

        要使用session,第一步當然是建立session了。那麼session在何時建立呢?當然還是在伺服器端程式運作的過程中建立的,不同語言實作的應用程式有不同建立session的方法,而在java中是通過調用httpservletrequest的getsession方法(使用true作為參數)建立的。在建立了session的同時,伺服器會為該session生成唯一的session id,而這個session id在随後的請求中會被用來重新獲得已經建立的session;在session被建立之後,就可以調用session相關的方法往session中增加内容了,而這些内容隻會儲存在伺服器中,發到用戶端的隻有session id;當用戶端再次發送請求的時候,會将這個session id帶上,伺服器接受到請求之後就會依據session id找到相應的session,進而再次使用之。正式這樣一個過程,使用者的狀态也就得以保持了。有關session的内容還比較多,在以後的post中,我還将繼續講述。

        綜上所述,http本身是一個無狀态的連接配接協定,為了支援用戶端與伺服器之間的互動,我們就需要通過不同的技術為互動存儲狀态,而這些不同的技術就是cookie和session了。

繼續閱讀