如果說HTTP是因特網的信使,那么HTTP報文就是它用來搬東西的包裹了。HTTP報文是在HTTP應用程序之間發送的簡單的格式化數據塊,每條報文都包含一條來自客戶端的請求,或者一條來自服務器的響應。它們由三個部分組成:由起始行、首部和實體的主體部分。本文將主要介紹HTTP報文起始行

報文語法
所有的HTTP報文都可以分為兩類:請求報文(request message)和響應報文(response message)。請求報文會向Web服務器請求一個動作,響應報文會將請求的結果返回給客戶端。請求和響應報文的基本報文結構相同

請求報文的格式:
<method> <request-URL> <version> <headers> <entity-body>
響應報文的格式:
<version><status><reason-phrase> <headers> <entity-body>
【方法(method)】
客戶端希望服務器對資源執行的動作。是一個單獨的詞,比如GET、HEAD或POST
【請求 URL(request-URL)】
命名了所請求資源,或者URL路徑組件的完整URL
【版本(version)】
報文所使用的HTTP版本,格式如下:
HTTP/<major>.<minor>
其中主要版本號(major)和次要版本號(minor)都是整數
【狀態碼(status-code)】
這三位數字描述了請求過程中所發生的情況。每個狀態碼的第一位數字都用于描述狀態的一般類別(“成功”、“出錯”等)
【原因短語(reason-phrase)】
數字狀態碼的可讀版本,包含行終止序列之前的所有文本
【首部(header)】
可以有零個或多個首部,毎個首部都包含一個名字,后面跟著一個冒號(:),然后是一個可選的空格,接著是一個值,最后是一個CRLF。首部是由一個空行(CRLF)結束的,表示了首部列表的結束和實體主體部分的開始
【實體的主體部分(entity-body)】
實體的主體部分包含一個由任意數據組成的數據塊。并不是所有的報文都包含實體的主體部分,有時,報文只是以一個CRLF結束
分類
所有的HTTP報文都以一個起始行作為開始。請求報文的起始行說明了要做些什么,響應報文的起始行說明發生了什么。下面將詳細介紹起始行的內容
請求行
請求報文請求服務器對資源進行一些操作。請求報文的起始行,或稱為請求行,包含了一個方法和一個請求URL,這個方法描述了服務器應該執行的操作,請求URL描述了要對哪個資源執行這個方法。請求行中還包含HTTP的版本,用來告知服務器,客戶端使用的是哪種HTTP。所有這些字段都由空格符分隔
響應行
響應報文承載了狀態信息和操作產生的所有結果數據,將其返回給客戶端。響應報文的起始行,或稱為響應行,包含了響應報文使用的HTTP版本、數字狀態碼,以及描述操作狀態的文本形式的原因短語。所有這些字段都由空格符進行分隔
方法
請求的起始行以方法作為開始,方法用來告知服務器要做些什么
HTTP常用方法共以下8種
GET:獲取資源
POST:傳輸實體主體
PUT:傳輸文件
HEAD:獲取報文首部
DELETE:刪除文件
OPTIONS:詢問支持的方法
TRACE:追蹤路徑
CONNECT:要求用隧道協議連接代理
GET
GET是最常用的方法。通常用于請求服務器發送某個資源


HEAD
HEAD方法與GET方法的行為很類似,但服務器在響應中只返回首部。不會返回實體的主體部分。這就允許客戶端在未獲取實際資源的情況下,對資源的首部進行檢査。使用HEAD,可以:
1、在不獲取資源的情況下了解資源的情況(比如,判斷其類型);
2、通過査看響應中的狀態碼,看看某個對象是否存在;
3、通過査看首部,測試資源是否被修改


PUT
與GET從服務器讀取文檔相反,PUT方法會向服務器寫入文檔。就像FTP協議的文件上傳一樣,要求在請求報文的主體中包含文件內容,然后保存到請求URI指定的位置
但是,由于HTTP/1.1的PUT方法自身不帶驗證機制,任何人都可以上傳文件,存在安全性問題,因此一般的Web網站不使用該方法。若配合Web應用程序的驗證機制,或架構設計采用REST(REpresentational State Transfer,表征狀態轉移)標準的同類Web網站,就可能會開放使用PUT方法

POST
POST方法起初是用來向服務器輸入數據的。實際上,通常會用它來支持html的表單


TRACE
TRACE請求會在目的服務器端發起一個“環回”診斷。行程最后一站的服務器會彈回一條TRACE響應,并在響應主體中攜帶它收到的原始請求報文。這樣客戶端就可以査看在所有中間HTTP應用程序組成的請求/響應鏈上,原始報文是否,以及如何被毀壞或修改過
發送請求時,在Max-Forwards首部字段中填入數值,每經過一個服務器端就將該數字減 1,當數值剛好減到0時,就停止繼續傳輸,最后接收到請求的服務器端則返回狀態碼 200 OK 的響應
但是,TRACE方法本來就不怎么常用,再加上它容易引發XST(Cross-Site Tracing,跨站追蹤)攻擊,通常就更不會用到了

OPTIONS
OPTIONS方法請求Web服務器告知其支持的各種功能。可以詢問服務器通常支持哪些方法,或者對某些特殊資源支持哪些方法
這為客戶端應用程序提供了一種手段,使其不用實際訪問那些資源就能判定訪問各種資源的最優方式


DELETE
DELETE方法所做的事情就是請服務器刪除請求URL所指定的資源
但是,HTTP/1.1 的 DELETE 方法本身和 PUT 方法一樣不帶驗證機制,所以一般的Web網站也不使用DELETE方法。當配合Web應用程序的驗證機制,或遵守REST標準時還是有可能會開放使用的

CONNECT
CONNECT方法要求在與代理服務器通信時建立隧道,實現用隧道協議進行TCP通信。主要使用SSL(Secure Sockets Layer,安全套接層)和TLS(Transport Layer Security,傳輸層安全)協議把通信內容加密后經網絡隧道傳輸
擴展方法
HTTP被設計成字段可擴展的,這樣新的特性就不會使老的軟件失效了。擴展方法指的就是沒有在HTTP/1.1規范中定義的方法。服務器會為它所管理的資源實現一些HTTP服務,這些方法為開發者提供了一種擴展這些HTTP服務能力的手段。下面表中列出的這些方法是WebDAV HTTP擴展包含的所有方法,這些方法有助于通過HTTP將Web內容發布到Web服務器上去

版本
HTTP協議有幾個版本,HTTP應用程序要盡量強健地處理各種不同的HTTP協議變體
【HTTP/0.9】
HTTP的1991原型版本稱為HTTP/0.9。這個協議有很多嚴重的設計缺陷,只應該用于與老客戶端的交互。HTTP/0.9只支持GET方法,不支持多媒體內容的MIME類型、各種HTTP首部,或者版本號。HTTP/0.9定義的初衷是為了獲取簡單的HTML對象,它很快就被H1TP/1.0取代了
【HTTP/1.0】
1.0是第一個得到廣泛使用的HTTP版本。HTTP/1.0添加了版本號、各種HTTP首部、一些額外的方法,以及對多媒體對象的處理,HTTP/1.0使得包含生動圖片的Web頁面和交互式表格成為可能,而這些頁面和表格促使萬維網為人們廣泛地接受。這個規范從未得到良好地說明。在這個HTTP協議的商業演進和學術研究都在快速進行的時代,它集合了一系列的最佳實踐
【HTTP/1.0】
在20世紀90年代中葉,很多流行的Web客戶端和服務器都在飛快地向HTTP中添加各種特性,以滿足快速擴張且在商業上十分成功的萬維網的需要。其中很多特性,包括持久的keep-alive連接,虛擬主機支持,以及代理連接支持都被加入到HTTP之中,并成為非官方的事實標準。這種非正式的HTTP擴展版本通常稱為 HTTP/1.0+
【HTTP/1.1】
HTTP/1.1重點關注的是校正HTTP設計中的結構性缺陷,明確語義,引入重要的性能優化措施,并刪除一些不好的特性。HTTP/1.1還包含了對更復雜的Web應用程序和部署方式的支持。HTTP/1.1是當前使用的HTTP版本
【HTTP-NG(又名HTTP/2.0)】
HTTP-NG是HTTP/1.1后繼結構的原型建議,它重點關注的是性能的大幅優化,以及更強大的服務邏輯遠程執行框架。在與HTTP/1.1完全語義兼容的基礎上,進一步減少了網絡延遲
隨著2015年5月14日HTTP/2協議正式版的發布,越來越多的網站和第三方CDN服務開始啟用HTTP/2。HTTP/2是新一代的 HTTP,也是HTTP的未來
狀態碼
HTTP狀態碼負責表示客戶端HTTP請求的返回結果、標記服務器端的處理是否正常、通知出現的錯誤等工作。HTTP狀態碼被分成了五大類,不同的類型代表不同類別的狀態碼
1XX Informational(信息性狀態碼) 表示接收的請求正在處理 2XX Success(成功狀態碼) 表示請求正常處理完畢 3XX Redirection(重定向狀態碼) 表示需要進行附加操作以完成請求 4XX Client Error(客戶端錯誤狀態碼) 表示服務器無法處理請求 5XX Server Error(服務器錯誤狀態碼) 表示服務器處理請求出錯
只要遵守狀態碼類別的定義,即使改變RFC2616中定義的狀態碼,或服務器端自行創建狀態碼都沒問題
僅記錄在RFC2616上的HTTP狀態碼就達40種,若再加上WebDAV(Web-based Distributed Authoring and Versioning,基于萬維網的分布式創作和版本控制)(RFC4918、5842)和附加HTTP狀態碼(RFC6585)等擴展,數量就達60余種。但實際上經常使用的大概只有十幾種
【1XX】
該部分狀態碼是信息性狀態碼,只有兩個
【2XX】
客戶端發起請求時,這些請求通常是成功的。服務器有一組用來表示成功的狀態碼,分別對應不同類型的請求
【3XX】
重定向狀態碼要么告知客戶端使用替代位置來訪問他們所感興趣的資源,要么就提供一個替代的響應而不是資源的內容。如果資源已被移動,可發送一個重定向狀態碼和一個可選的Location首部來告知客戶端資源已被移走,以及現在可以在哪里找到它。這樣,瀏覽器就可以在不打擾使用者的情況下,透明地轉入新的位置了
【4XX】
有時客戶端會發送一些服務器無法處理的東西,比如格式錯誤的請求報文,或者請求一個不存在的URL
瀏覽網頁時,我們都看到過404 Not Found錯誤碼——這只是服務器在告訴我們,它對我們請求的資源一無所知。很多客戶端錯誤都是由瀏覽器來處理的。只有少量錯誤,比如404,還是會穿過瀏覽器來到用戶面前
【5XX】
有時客戶端發送了一條有效請求,服務器自身卻出錯了。這可能是客戶端碰上了服務器的缺陷,或者服務器上的子元素,比如某個網關資源出了錯。代理嘗試著代表客戶端與服務器進行交流時,經常會出現問題。代理會發布5XX服務器錯誤狀態碼來描述所遇到的問題



記錄一下,隨時可以翻閱,三天不練手生,三天不看眼生,好記性不如爛筆頭。