HTTP響應報文與工作原理詳解

chenhanzhun的部落格發表於2015-01-27

超文字傳輸協議(Hypertext Transfer Protocol,簡稱HTTP)是應用層協議。HTTP 是一種請求/響應式的協議,即一個客戶端與伺服器建立連線後,向伺服器傳送一個請求;伺服器接到請求後,給予相應的響應資訊。

HTTP 請求報文

HTTP 請求報文由請求行、請求頭部、空行 和 請求包體 4 個部分組成,如下圖所示:

HTTP 請求報文由請求行、請求頭部、空行 和 請求包體 4 個部分組成

下面對請求報文格式進行簡單的分析:

請求行:請求行由方法欄位、URL 欄位 和HTTP 協議版本欄位 3 個部分組成,他們之間使用空格隔開。常用的 HTTP 請求方法有 GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT;

● GET:當客戶端要從伺服器中讀取某個資源時,使用GET 方法。GET 方法要求伺服器將URL 定位的資源放在響應報文的資料部分,回送給客戶端,即向伺服器請求某個資源。使用GET 方法時,請求引數和對應的值附加在 URL 後面,利用一個問號(“?”)代表URL 的結尾與請求引數的開始,傳遞引數長度受限制。例如,/index.jsp?id=100&op=bind。

● POST:當客戶端給伺服器提供資訊較多時可以使用POST 方法,POST 方法向伺服器提交資料,比如完成表單資料的提交,將資料提交給伺服器處理。GET 一般用於獲取/查詢資源資訊,POST 會附帶使用者資料,一般用於更新資源資訊。POST 方法將請求引數封裝在HTTP 請求資料中,以名稱/值的形式出現,可以傳輸大量資料;

請求頭部:請求頭部由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號“:”分隔。請求頭部通知伺服器有關於客戶端請求的資訊,典型的請求頭有:

● User-Agent:產生請求的瀏覽器型別;

● Accept:客戶端可識別的響應內容型別列表;星號 “ * ” 用於按範圍將型別分組,用 “ */* ” 指示可接受全部型別,用“ type/* ”指示可接受 type 型別的所有子型別;

● Accept-Language:客戶端可接受的自然語言;

● Accept-Encoding:客戶端可接受的編碼壓縮格式;

● Accept-Charset:可接受的應答的字符集;

● Host:請求的主機名,允許多個域名同處一個IP 地址,即虛擬主機;

● connection:連線方式(close 或 keepalive);

● Cookie:儲存於客戶端擴充套件欄位,向同一域名的服務端傳送屬於該域的cookie;

空行:最後一個請求頭之後是一個空行,傳送回車符和換行符,通知伺服器以下不再有請求頭;

請求包體:請求包體不在 GET 方法中使用,而是在POST 方法中使用。POST 方法適用於需要客戶填寫表單的場合。與請求包體相關的最常使用的是包體型別 Content-Type 和包體長度 Content-Length;

HTTP 響應報文

HTTP 響應報文由狀態行、響應頭部、空行 和 響應包體 4 個部分組成,如下圖所示:

下面對響應報文格式進行簡單的分析:

狀態行:狀態行由 HTTP 協議版本欄位、狀態碼和狀態碼的描述文字 3 個部分組成,他們之間使用空格隔開;

● 狀態碼由三位數字組成,第一位數字表示響應的型別,常用的狀態碼有五大類如下所示:

1xx:表示伺服器已接收了客戶端請求,客戶端可繼續傳送請求;

2xx:表示伺服器已成功接收到請求並進行處理;

3xx:表示伺服器要求客戶端重定向;

4xx:表示客戶端的請求有非法內容;

5xx:表示伺服器未能正常處理客戶端的請求而出現意外錯誤;

● 狀態碼描述文字有如下取值:

200 OK:表示客戶端請求成功;

400 Bad Request:表示客戶端請求有語法錯誤,不能被伺服器所理解;

401 Unauthonzed:表示請求未經授權,該狀態程式碼必須與 WWW-Authenticate 報頭域一起使用;

403 Forbidden:表示伺服器收到請求,但是拒絕提供服務,通常會在響應正文中給出不提供服務的原因;

404 Not Found:請求的資源不存在,例如,輸入了錯誤的URL;

500 Internal Server Error:表示伺服器發生不可預期的錯誤,導致無法完成客戶端的請求;

503 Service Unavailable:表示伺服器當前不能夠處理客戶端的請求,在一段時間之後,伺服器可能會恢復正常;

響應頭部:響應頭可能包括:

Location:Location響應報頭域用於重定向接受者到一個新的位置。例如:客戶端所請求的頁面已不存在原先的位置,為了讓客戶端重定向到這個頁面新的位置,伺服器端可以發回Location響應報頭後使用重定向語句,讓客戶端去訪問新的域名所對應的伺服器上的資源;

Server:Server 響應報頭域包含了伺服器用來處理請求的軟體資訊及其版本。它和 User-Agent 請求報頭域是相對應的,前者傳送伺服器端軟體的資訊,後者傳送客戶端軟體(瀏覽器)和作業系統的資訊。

Vary:指示不可快取的請求頭列表;

Connection:連線方式;

對於請求來說:close(告訴 WEB 伺服器或者代理伺服器,在完成本次請求的響應後,斷開連線,不等待本次連線的後續請求了)。keepalive(告訴WEB伺服器或者代理伺服器,在完成本次請求的響應後,保持連線,等待本次連線的後續請求);

對於響應來說:close(連線已經關閉); keepalive(連線保持著,在等待本次連線的後續請求); Keep-Alive:如果瀏覽器請求保持連線,則該頭部表明希望WEB 伺服器保持連線多長時間(秒);例如:Keep-Alive:300;

WWW-Authenticate:WWW-Authenticate響應報頭域必須被包含在401 (未授權的)響應訊息中,這個報頭域和前面講到的Authorization 請求報頭域是相關的,當客戶端收到 401 響應訊息,就要決定是否請求伺服器對其進行驗證。如果要求伺服器對其進行驗證,就可以傳送一個包含了Authorization 報頭域的請求;

空行:最後一個響應頭部之後是一個空行,傳送回車符和換行符,通知伺服器以下不再有響應頭部。

響應包體:伺服器返回給客戶端的文字資訊;

HTTP 工作原理

HTTP 協議採用請求/響應模型。客戶端向伺服器傳送一個請求報文,伺服器以一個狀態作為響應。

以下是 HTTP 請求/響應的步驟:

● 客戶端連線到web伺服器:HTTP 客戶端與web伺服器建立一個 TCP 連線;

● 客戶端向伺服器發起 HTTP 請求:通過已建立的TCP 連線,客戶端向伺服器傳送一個請求報文;

● 伺服器接收 HTTP 請求並返回 HTTP 響應:伺服器解析請求,定位請求資源,伺服器將資源副本寫到 TCP 連線,由客戶端讀取;

● 釋放 TCP 連線:若connection 模式為close,則伺服器主動關閉TCP 連線,客戶端被動關閉連線,釋放TCP 連線;若connection 模式為keepalive,則該連線會保持一段時間,在該時間內可以繼續接收請求;

● 客戶端瀏覽器解析HTML內容:客戶端將伺服器響應的 html 文字解析並顯示;

例如:在瀏覽器位址列鍵入URL,按下回車之後會經歷以下流程:

1、瀏覽器向 DNS 伺服器請求解析該 URL 中的域名所對應的 IP 地址;

2、解析出 IP 地址後,根據該 IP 地址和預設埠 80,和伺服器建立 TCP 連線;

3、瀏覽器發出讀取檔案(URL 中域名後面部分對應的檔案)的HTTP 請求,該請求報文作為 TCP 三次握手的第三個報文的資料傳送給伺服器;

4、伺服器對瀏覽器請求作出響應,並把對應的 html 文字傳送給瀏覽器;

5、釋放 TCP 連線;

6、瀏覽器將該 html 文字並顯示內容;

HTTP 無狀態性

HTTP 協議是無狀態的(stateless)。也就是說,同一個客戶端第二次訪問同一個伺服器上的頁面時,伺服器無法知道這個客戶端曾經訪問過,伺服器也無法分辨不同的客戶端。HTTP 的無狀態特性簡化了伺服器的設計,使伺服器更容易支援大量併發的HTTP 請求。

HTTP 持久連線

HTTP1.0 使用的是非持久連線,主要缺點是客戶端必須為每一個待請求的物件建立並維護一個新的連線,即每請求一個文件就要有兩倍RTT 的開銷。因為同一個頁面可能存在多個物件,所以非持久連線可能使一個頁面的下載變得十分緩慢,而且這種短連線增加了網路傳輸的負擔。HTTP1.1 使用持久連線keepalive,所謂持久連線,就是伺服器在傳送響應後仍然在一段時間內保持這條連線,允許在同一個連線中存在多次資料請求和響應,即在持久連線情況下,伺服器在傳送完響應後並不關閉TCP 連線,而客戶端可以通過這個連線繼續請求其他物件。

HTTP/1.1 協議的持久連線有兩種方式:

● 非流水線方式:客戶在收到前一個響應後才能發出下一個請求;

● 流水線方式:客戶在收到 HTTP 的響應報文之前就能接著傳送新的請求報文;

最後給出一個具體例子:

Remote Address:116.57.254.104:80   
Request URL:http://hr.tencent.com/   
Request Method:GET   
Status Code:200 OK   

Request Headers   
GET / HTTP/1.1   
Host: hr.tencent.com   
Connection: keep-alive   
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8   
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36   
Accept-Encoding: gzip,deflate,sdch   
Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4   
Cookie: pgv_pvi=2098703360; PHPSESSID=bc7onl0dojbsatscsfv79pds77; pgv_info=ssid=s1454606128;    
        pgv_pvid=926725350; ts_uid=4084753309   

Response Header   
HTTP/1.1 200 OK   
Server: nginx   
Date: Mon, 26 Jan 2015 01:09:10 GMT   
Content-Type: text/html;charset=utf-8   
Content-Length: 3631   
Connection: keep-alive   
X-Powered-By: PHP/5.3.10   
Expires: Thu, 19 Nov 1981 08:52:00 GMT   
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0   
Pragma: no-cache   
Vary: Accept-Encoding   
Content-Encoding: gzip

從請求報文可以知道:

GET / HTTP/1.1

請求方法 GET 表示一個讀取請求,將從伺服器獲得網頁資料,/表示URL 的路徑,URL 總是以/開頭,/就表示首頁,最後的HTTP/1.1 指示採用的 HTTP 協議版本是 1.1;請求域名如下所示:

Host: hr.tencent.com

響應報文如下:

HTTP/1.1 200 OK   
Server: nginx

相關文章