HTTP協議無論是請求報文還是迴應報文,都分爲以下4個部分。
(1)報文頭(initial line),比如訪問百度的例子,”GET http://www.baidu.com/favicon.ico HTTP/1.1”表示用GET方法請求http://www.baidu.com/favicon.ico這個文件,用的是HTTP/1.1協議。
(2)0個或者多個請求頭(header line),例如Accept-Language:en。
(3)空行(作爲header lines的結束)
(4)可選的消息體
HTTP協議是基於行的協議,每一行以\r\n作爲分隔符,報文頭通常表明報文的類型,比如請求的類型。且報文頭只佔一行,請求頭附帶一些特殊信息,每個請求佔一行,其格式爲name:value,即以分號作爲分割;空行也就以一個\r\n分隔,可選的body通常包含數據,例如服務器返回的某個靜態HTML文件的內容。
下面使用抓包工具wireshark,設置tcp.port==80,只關注http的端口通信。
在瀏覽器輸入http://www.baidu.com/favicon.ico並回車。
可以看到第一行:
GET /favicon.ico HTTP/1.1\r\n
這個表明用GET方法,HTTP/1.1協議去獲取favicon.ico文件。
1.HTTP請求方法
HTTP/1.1協議中定義了9種方法,來表明Request-URL指定的資源的不同操作方式,如下所述。
(1)OPTIONS:返回服務器針對特定資源所支持的HTTP請求方法,也可以利用web服務器發送”*”的請求來測試服務器的功能性。
(2)HEAD:向服務器索要與GET方法請求一致的響應,只不過響應體將不會被返回,這種方法可以在不必傳輸整個響應內容的情況下,就可以獲取包含在響應消息頭的元信息,該方法常用於測試超鏈接的有效性,是否可以訪問,以及最近是否更新等信息。
(3)GET:向特定資源發出請求。注意,GET方法不應當用於產生副作用的操作中,例如web app中的應用,其中一個原因是GET可能會被網絡蜘蛛等隨意訪問。
(4)POST:向特定資源提交數據進行處理請求。數據被包含在請求體中,POST請求可能會導致新的資源的建立或對已有資源的修改。
(5)PUT:向指定資源位置上傳最新內容。
(6)DELETE:請求服務器刪除Request-URL所標識的資源。
(7)TRACE:回顯服務器收到的請求,主要用於測試或診斷。
(8)CONNECT:HTTP/1.1協議中預留給能夠將連接改爲管道方式的代理服務器。
(9)PATCH:用來將局部修改應用於某一資源,該操作添加於規範RFC5789中。
方法名是區分大小寫的,當某個請求所針對的資源不支持對應的請求方法時,服務器應當返回狀態碼405,當服務器不認識或者不支持對應的請求方法時,應當返回狀態碼501。
HTTP服務器至少應該實現GET和HEAD方法,其他方法都是可選的。
2.HTTP常見的請求頭
在HTTP/1.1協議中,所有的請求頭(除了Host外)都是可選的。
(1)Host:發送請求時,該請求頭是必需的。主要用於被請求資源的Internet主機和端口號,它通常從HTTP URL中提取出來的,HTTP/1.1請求必須包含主機頭域,否則系統會以400狀態碼返回,例如上面的例子中,瀏覽器中輸入http://www.baidu.com/favicon.ico後,瀏覽器發送的請求消息中,就會包含Host請求頭域”Host:http://www.baidu.com”,此處使用的端口號80,如過指定端口號,則變成:“Host:端口號”。
(2)Connection:他的值通常只有2個,keep-alive和close,HTTP是一個請求響應模式的典型範例,即客戶端向服務器發送一個請求信息,服務器來響應這個消息。在之前的HTTP版本中,每個請求都被創建一個新的客戶端到服務器的連接,在這個連接上發送請求,然後接收請求,這種模式的好處就是簡單,容易理解和編程實現,但也有一個很大的缺點,就是效率很低,因此,keep-alive被提出用來解決效率低的問題。keep-alive使得客戶端到服務器的連接持續有效。當出現對服務器的後續請求時,keep-alive避免了建立或者重新建立連接。市場上大部分web服務器,包括iplanet,IIS和apache等,都支持HTTP的keep-alive功能。
對於提供靜態內容的網站來說,這個功能通常很有用,但是對於負擔較重的網站來說,這裏存在另外一個問題,雖然爲客戶保留打開的連接有一定的好處,但它同樣影響了性能,因爲在處理暫停期間,本來可以釋放的資源仍舊被佔用。當web服務器和應用服務器在同一臺機器上運行時,keep-alive功能對資源利用的影響尤其突出,此功能爲HTTP/1.1預設的功能,HTTP/1.0,加上keep-alivchcader也可以提供HTTP的持續作用功能。
(3)Accept:瀏覽器端可以接收的MIME類型。例如:Accept:text/html代表瀏覽器可以接收服務器回發的類型爲text/html,也就是我們常說的html文檔,如果服務器無法返回text/html類型的數據,服務器應該返回一個406錯誤(non acceptable),通配符(*)代表任意類型,例如Accept:*/*代表瀏覽器可以處理所有類型。
(4)Cache-Control:指定請求和響應遵循的緩存機制
(5)Accept-Encoding:瀏覽器聲明自己可以接收的編碼方法,通常說明是否支持壓縮並指定壓縮方法,Servlet能夠向支持gzip的瀏覽器返回gzip編碼的HTML頁面,許多情形下這種編碼可以5-10倍的下載時間。如果請求消息中沒有設置這個域,服務器假定客戶端對各種內容編碼都可以接受。一般設置Accept-Encoding: gzip, deflate, sdch\r\n
(6)Accept-Language:瀏覽器聲明自己接收的語言,語言跟字符集的區別可以理解爲:中文是語言,中文有多種字符集,比如,big5、gb2312、gbk等,例如:Accept-Language:cn-us。如果請求消息中沒有設置這個報頭域,則服務器假定客戶端對各種語言都可以接受。上面的例子中:Accept-Language: zh-CN,zh;q=0.8\r\n
(7)Accept-Charset:瀏覽器可以接受的字符集。如果在請求消息中沒有設置這個域,默認時表示任何字符集都可以接受。
上面的例子中:
(8)User-Agent:用於告訴HTTP服務器,客戶端使用的操作系統和瀏覽器名稱和版本。
上面的列子中:
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0\r\n
3.HTTP迴應報文
先來看看訪問http://www.baidu.com/favicon.ico得到的返回包內容。
因爲訪問的是一張圖片,因此media type是Image。
第一行是報文頭,第一個字段表明HTTP協議版本,可以直接以請求報文爲準,第二個字段是status code,也就是返回碼,相當於請求的結果。
200表示成功、404表示資源不存在等。最後一個字段爲status code的可讀字符串。
返回碼由3位數字組成,第一個數字定義了響應的類型。且有5種可能的取值。
(1)1xx:指示信息,表示請求已接收,繼續處理。
(2)2xx: 成功,表示請求已被成功接收、理解、接受。
(3)3xx:重定向,要完成請求必須進行更進一步的操作。
(4)4xx:客戶端錯誤,請求有語法錯誤,或請求無法實現。
(5)5xx:服務器端錯誤,服務器未能實現合法的請求。
常見返回碼和其狀態描述說明如下:
200 OK 客戶端請求成功
400 Bad Request 客戶端請求有語法錯誤,不能被服務器所理解
401 Unauthorized 請求未經授權
403 Forbidden 服務器收到請求,但是拒絕提供服務
404 Not found 請求資源不存在,比如輸入錯誤URL
500 Internet Server Error 服務器發生不可以預期的錯誤
503 Server Unavailable 服務器當前不能處理客戶端的請求,一段時間後可能恢復正常。
Date:表示日期
Server:服務器軟件