HTTP協議——HTTP報文組成
一、報文流
HTTP報文是在HTTP應用程式之間傳送的資料塊,這些資料塊以一些文字形式的元資訊開頭,這些資訊描述了報文的內容及含義。這些報文在客戶端、伺服器和代理之間流動。
1、報文流入源端伺服器
http使用術語流入(inbound)和流出(outbound)來描述事務處理的方向;報文流入源伺服器,工作完成後,流回使用者的Agent代理中。
2、報文向下遊流動
HTTP報文會像河水一樣流動,不管是請求報文還是響應報文,所有報文都會向下遊流動。所有報文的傳送者都在接受者的上游。
二、報文的組成
HTTP報文是簡單的格式化資料塊,每條報文都包含一條來自客戶端的請求,或者一條來自伺服器的響應。它們由三個部分組成:對報文進行描述的其實行、包含屬性的首部塊、以及可選的、包含資料的主題部分。
起始行和首部就是由行分隔的 ASCII文字。每行都以一個由2個字元組成的行終止序列作為結束,包括一個回車符(ASCII碼13)和一個換行符(ASCII碼10),這個行終止序列可以寫為CRLF。(穩健的應用程式也應該接受單個換行符作為行的終止)
實體的主體和報文的主體是一個可選的資料塊。與起始行和首部不同的是,主體中可包含文字或二進位制資料,也可以為空如上圖,Content-type行說明了主體是一個純文字文件,Content-length說明了主體有19位元組。
1、報文的語法
HTTP報文分為請求報文和響應報文。請求報文會向Web伺服器請求一個動作,響應報文會將請求的結果返回給客戶端。請求和響應報文的基本報文結構相同。
請求報文的格式
<method><request-URL><version><headers>
<entity-body>
響應報文的格式
<version><status><reason-phrase><headers>
<entity-body>
各部分的簡要描述
方法(method)
客戶端希望伺服器對資源執行的動作,是一個單獨的詞,如GET,POST等。
請求RUL(request-URL)
命名了所請求資源,或者URL路徑元件的完整URL。如果直接與伺服器進行對話,只要URL的路徑元件是資源的絕對路徑,通常就不會有什麼問題——伺服器可以嘉定自己是URL的主機/埠。
版本(version)
報文鎖使用的HTTP版本,其格式如下:
HTTP/<major>.<minor>
其中主要版本號(major)和次要版本號(minor)都是整數。
狀態碼(status-code)
這三位數字描述了請求過程中所發生的情況。每個狀態碼的第一位數字用於描述狀態的一般型別(“成功”、“出錯”等)。
原因短語(reason-phrase)
數字狀態碼的可讀版本,包含行種植序列之前的所有文字。原因短語只對人類有意義。
首部(header)
可以有另個或多個首部,每個首部都包含一個名字,後面跟著一個冒號(;),然後是一個可選的空格,接著是一個值,最後是一個CRLF。首部是由一個空行(CRLF)結束的,表示了首部列表的結束和實體主體部分的開始。
實體的主體部分(entity-body)
實體的主體部分包含一個由任意資料組成的資料塊。並不是所有的報文都包含實體的主體部分,有時候,報文只是以一個CRLF結束。
2、起始行
所有的HTTP報文都是以一個起始行作為開始。請求報文的起始行說明了要做些什麼。響應報文的起始行說明發生了什麼。
請求行
請求報文請求伺服器對資源進行一些操作。請求行(即請求報文的起始行),包含一個方法和一個請求URL,這個方法描述了伺服器應該執行的操作,請求URL描述了要對哪個資源執行這個方法。請求行中包含HTTP的版本,用來告知伺服器,客戶端使用的是那種HTTP。
如下例子:
請求方法是GET,請求URL為/test/hi-there.txt,版本為HTTP/1.1。
響應行
響應報文承載了狀態資訊和操作產生的所有結果資料,將其返回給客戶端。響應行(即響應報文的起始行),包含了響應報文使用的HTTP版本、數字狀態碼,以及描述操作狀態的文字形式的原因短語。
這些欄位都由空格符進行分隔,如下例子:
HTTP版本為HTTP/1.0,狀態碼為200,原因短語為OK,表示文件已經唄成功返回來。
方法
請求的起始行以方法作為開始,方法用來告知伺服器要做些什麼。
HTTP規範中定義了一組常用的請求方法,如GET、POST,具體如下:
整體範圍 | 已定義範圍 | 分類 |
GET | 從伺服器獲取一份文件 | 否 |
HEAD | 只從伺服器獲取文件的首部 | 否 |
POST | 向伺服器傳送需要處理的資料 | 是 |
PUT | 將請求的主體部分儲存在伺服器上 | 是 |
TRACE | 對可能經過代理伺服器傳送到伺服器上去的報文進行追蹤 | 否 |
OPTIONS | 決定可以在伺服器上執行哪些方法 | 否 |
DELETE | 從伺服器上刪除一份文件 | 否 |
狀態碼
狀態碼用來告訴客戶端,發生了什麼事;狀態碼位於響應的起始行中。狀態碼在每條響應報文的起始行中返回的,以一個數字和一個可讀的狀態組成;數字碼便於程式進行差錯處理,原因短語則便於理解。具體的狀態碼分類如下:
整體範圍 | 已定義範圍 | 分類 |
100~199 | 100~101 | 資訊提示 |
200~299 | 200~206 | 成功 |
300~399 | 300~305 | 重定向 |
400~499 | 400~415 | 客戶端錯誤 |
500~599 | 500~505 | 伺服器錯誤 |
當前HTTP版本只為每類狀態定義了幾個程式碼,如果收到不認識的狀態碼,可能有人將其作為當前協議的擴充套件定義的。可以根據其所在範圍,將它當作那個類別中一個普通的成員來處理。
原因短語
原因短語為狀態碼提供了文字形式的解釋,和狀態碼成對出現,是狀態碼的可讀版本,應用程式將其傳給客戶,說明在請求期間發生了什麼;稍後會整理出一些狀態碼和其建議使用的一些原因短語版本號
版本號會以http/x、y的形式出現在請求和響應報文的起始行中,為應用程式提供了一種將自己遵循的協議版本告知對方的方式
通訊時最好使請求和響應的版本號保持一致,否則很容易造成誤解,使程式無法識別
PS:版本號不會被當做分數處理,每個數字都是獨立的,比如,HTTP/2.22版本高於HTTP/2.3
3、首部
http首部欄位向請求和響應報文中新增一些附加資訊;本質來講,他們知識一些名/值對的列表。首部分類
HTTP規範定義了集中首部欄位,應用程式也可以隨意發明自己所用的首部。HTTP首部可以分為以下幾類。 通用首部:即可出現在請求報文中,也可出現在響應報文中
請求首部:提供更多有關請求的資訊
響應首部:提供更多有關響應的資訊
實體首部:描述主體的長度和內容,或者資源本身
擴充套件首部:規範中沒有定義的新首部
每個http首部都有一種簡單的語法:名字後面是冒號(:),然後跟上可選的空格,再跟上欄位值,最後以一個CRLF結束。
首部延續行
將長的首部行分為多行可以提高可讀性,多出來的每行前面至少要有一個空格或製表符(tab)。例如:
在這個例子中,響應報文裡包含了一個Server首部,其值被劃分成了多個延續行。該首部的完整值為Test Server Version 1.0。後面戶詳細介紹所有HTTP首部。
4、實體的主體部分
HTTP報文的第三部分是可選的實體主體部分。實體的主體是HTTP報文的複合,就是HTTP要傳輸的內容。
HTTP報文可以承載很多型別的數字資料:圖片、視訊、HTML文件、軟體應用程式、信用卡事務、電子郵件等。