HTTP的特性
- HTTP是構建於TCP/IP協議之上,是應用層協議,默認端口號80
- HTTP協議是無連接無狀態的
HTTP報文
請求報文
HTTP協議是以ASCⅡ碼傳輸,建立在TCP/IP協議之上的應用層規范。
HTTP請求報文由請求行(request line)、請求頭部(header)、空行和請求數據四個部分組成,下圖是請求報文的一般格式。

1、請求行
請求行是由請求方法、url字段以及HTTP協議版本字段三個部分組成,它們用空格分開。
HTTP協議的請求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。
而常見的有如下幾種:
1.1 GET
當客戶端要從服務器讀取數據時,點擊網頁上的鏈接,或者通過在瀏覽器的地址欄輸入網址來瀏覽網頁的,使用的都是GET方式。GET的方法要求服務器將URL定位的資源放在響應報文的數據部分,回送給客戶端。使用GET的方法,請求參數和對應的值附加在URL后面,利用問號 (?),代表URL的結尾和請求參數的開始,傳遞的參數長度受到限制。例如,/index.html?id=1&password=123,這樣通過GET的方式傳遞的數據直接顯示在地址上,所以我們可以將請求以鏈接的方式發送給接收方。以谷歌搜索 “domety” 為例,request的格式如下:

可以看到GET的請求一般不包含“請求內容”的部分,請求數據以地址的形式表現在 請求行中,地址 ? 之后的部分就是通過GET發送的數據,我們可以在地址欄中看到各種數據之間用 & 符號隔開。
-
但是這種方式顯然不能傳遞私密的數據。
-
另外不同瀏覽器對地址的字符長度限制有不同的數據,一般最多不超過1024個字符,所以大量的數據傳輸,不適合使用GET方式。
1.2 POST
對於以上適合使用GET方式的情況下,可以使用POST方式,因為使用POST的方法允許客戶端給服務端提供較多的信息。POST將請求參數封裝在HTTP的請求數據中,可以大量的傳遞數據,理論上對數據得大小的沒有限制,但實際各個WEB服務器會規定對post提交數據大小進行限制。而且可以不顯示在URL中。下圖是用wireshark抓的一個POST請求的報文,紅色為請求報文,藍色為響應報文

可以看到POST方式的請求行中不包括字符串數據,這些內容保存在“請求內容”部分,各個數據之間也是以 & 符號隔開。
POST方法向服務器提交數據,比如表單的數據的提交。GET的方法一般用於獲取/查詢資源信息。
2、請求頭部
請求頭部由鍵值對組成,關鍵字和值之間用 : 分開。請求頭封裝了有關客戶端請求的信息,典型的請求頭有:
請求頭 | 含義 |
---|---|
User-Agent | 產生請求的瀏覽器類型,User-Agent請求報頭域允許客戶端將它的操作系統、瀏覽器和其它屬性告訴服務器 |
Accept | 客戶端可識別的響應內容類型列表。eg:Accept:image/gif,表明客戶端希望接受GIF圖象格式的資源;Accept:text/html,表明客戶端希望接受html文本。 |
Accept-Language | 客戶端可接受的自然語言 |
Accept-chartset | 客戶端可接受應答的字符集。eg:Accept-Charset:iso-8859-1,gb2312.如果在請求消息中沒有設置這個域,缺省是任何字符集都可以接受。 |
Accept-Encoding | 客戶端可接受的編碼壓縮格式 |
HOST | 請求的主機名稱,允許多個域名同處一個IP之地,即虛擬主機 |
Connection | 連接方式(close或keep-alive) |
Cookie | 存儲於客戶端擴展字段,向同一域名的服務端發送該域的cookie |
Authorization | Authorization請求報頭域主要用於證明客戶端有權查看某個資源。當瀏覽器訪問一個頁面時,如果收到服務器的響應代碼為401(未授權),可以發送一個包含Authorization請求報頭域的請求,要求服務器對其進行驗證。 |
3、空行
最后一個請求頭之后是一個空行,發送回車符和換行符,通知服務器以下不會再有請求頭。
4、請求數據
請求數據不再GET方法中使用,而是在POST方法中使用。POST方法適用於客戶端提交表單。與請求數據相關的最常使用的請求頭是包體類型 Content-Type 和包體長度 Content-Length
響應報文
HTTP響應報文是由狀態行、響應頭部、空行和響應包體四個部分組成,如下圖所示

這響應中狀態行(status line)代替了請求行。狀態行通過提供一個狀態碼來說明請求情況。
1、狀態行
狀態行由HTTP協議版本(HTTP-Version),狀態碼(Statue-Code) 和 狀態碼描述文本(Reason-Phrase) 三個部分組成,它們之間用空格隔開;
狀態碼有三位數字組成,第一位定義了響應的類別,可能有五種取值:
- 1xx:表示服務端已經接收到客戶端請求,客戶端可以繼續發送請求;
- 2xx:表示服務端已經成功接收請求並處理;
- 3xx:表示服務器要求客戶端重定向;
- 4xx:客戶端請求有問題;
- 5xx:服務端未能正常處理客戶端的請求出現錯誤;
常見狀態碼描述文本有如下:
- 200 OK:請求成功;
- 400 Bad Request:客戶端請求語法有問題,不能被服務端理解;
- 401 Unauthorized:請求未經授權,必須與Authorization請求報頭域一起使用(eg:BASE64用戶身份驗證);
- 403 Forbidden:服務器收到請求但是拒絕提供服務,通常會在響應正文中給出不提供服務的原因;
- 404 Not Found:請求的資源不存在,eg,輸錯了URL;
- 500 Internal Server Error:服務器發生錯誤,無法完成客戶端請求;
- 503 Service Unavailable:表示服務器當前不能處理客戶端請求,一段時間之后可能恢復正常;
2、響應頭
響應頭可能包括以下信息:
響應頭 | 描述 |
---|---|
Server | Server 響應報頭域包含了服務器用來處理請求的軟件信息及其版本。它和 User-Agent 請求報頭域是相對應的,前者發送服務器端軟件的信息,后者發送客戶端軟件(瀏覽器)和操作系統的信息。 |
Vary | 指示不可緩存的請求頭列表 |
Connection | 連接方式 |
www-Authenticate | WWW-Authenticate響應報頭域必須被包含在401 (未授權的)響應消息中,這個報頭域和前面講到的Authorization 請求報頭域是相關的,當客戶端收到 401 響應消息,就要決定是否請求服務器對其進行驗證。如果要求服務器對其進行驗證,就可以發送一個包含了Authorization 報頭域的請求 |
3、響應包體
服務器返回給客戶端的文本信息
以下是用wireshark抓的一段響應報文

HTTP無狀態性
HTTP協議是無狀態的(stateless)。也就是說,同一個客戶端第二次訪問同一個服務器上面的頁面時,服務器無法得知這個客戶端曾經訪問過,服務器無法辨別不同的客戶端。HTTP的無狀態性簡化了服務器的設計,是服務器更容易支持大量並發的HTTP請求。
HTTP協議是采用請求-響應的模型。客戶端向服務端發送一個請求報文,服務端以一個狀態作為回應。
當使用普通模式,即非keep-alive模式時,每個請求-應答都要重新建立一個連接,連接完成后立即斷開;
HTTP1.1 使用持久連接keep-alive,所謂持久連接,就是服務器在發送響應后仍然在一段時間內保持這條連接,允許在同一個連接中存在多次數據請求和響應,即在持久連接情況下,服務器在發送完響應后並不關閉TCP 連接,而客戶端可以通過這個連接繼續請求其他對象。
HTTP 長連接不可能一直保持,例如 Keep-Alive: timeout=5, max=100,表示這個TCP通道可以保持5秒,max=100,表示這個長連接最多接收100次請求就斷開。
HTTP 是一個無狀態協議,這意味着每個請求都是獨立的,Keep-Alive 沒能改變這個結果。另外,Keep-Alive也不能保證客戶端和服務器之間的連接一定是活躍的,在 HTTP1.1 版本中也如此。唯一能保證的就是當連接被關閉時你能得到一個通知,所以不應該讓程序依賴於 Keep-Alive 的保持連接特性,否則會有意想不到的后果。
瀏覽器控制台中的http報文
這里簡單的放一張瀏覽器控制台的http請求報文解析
