若是說 HTTP 是互聯網的信使, 那麼 HTTP 報文就是他用來搬東西的包裹了. --- 《HTTP 權威指南》html
HTTP 程序之間是經過互相發送 HTTP報文(如下簡稱報文) 來工做的,那麼瞭解報文相關的知識就很是有必要了。知道報文的結構、內部的字段以及各字段的功能等信息,這對之後的工做具備重要的意義。緩存
報文是 HTTP 程序之間傳遞的數據塊,這個數據塊內包含了發送者的目的、服務器返回的結果以及其餘相關信息。服務器
報文能夠分爲顧名就能思義的兩種:請求報文和響應報文。編碼
請求報文是客戶端發出的,向服務器請求資源的報文;響應報文就是服務端發出的,向客戶端進行回覆的報文。~(不管你的請求能不能實現,我總要回復你一下啊)~3d
程序之間進行通訊時會傳遞許多的報文,能夠想象現實中的河流,水在小河中流動,而報文在各個程序間流動,稱爲報文流。關於報文流有兩個概念:代理
流入(inbound)和流出(outbound) 這是個絕對的概念,這裏的絕對是對於服務器來講的絕對:流向服務器的報文流就是流入;從服務器發出(流出)的報文流就是流出。流入和流出只是對於服務器來講的,因此是絕對的。code
上下游的概念 (upstream & downstream) 這是個相對的概念。orm
對於報文的發送者來講,它就是這個報文的上游,後面接收到這個報文的節點就是他的下游;cdn
對於報文的接收者來講,它就是報文的下游,在它以前收到這個報文的節點就是他的上游;若是它繼續將這個報文傳遞下去,那麼接下來收到這個報文的就是它的下游。htm
如圖:
上圖中的請求報文流從客戶端流向服務器,中間通過了幾個代理,按流動的方向來看,代理1位於代理2的上游,而代理2位於代理3的上游。
而在響應流中,響應報文從服務器流向客戶端,中間通過了幾個一樣的代理。此時按流動的方向來看,代理3位於代理2的上游,而代理2位於代理1的上游。
因而可知,因爲報文只能向下流動,因此請求報文流中的上游就會成爲響應報文流中的下游。這就體現了報文流中上下游的相對性。~風水輪流轉?~
報文由3大部分組成,分別是:
這樣看起來有些難以理解,能夠用在淘寶買東西的過程打個比方:先決定本身要買什麼,收貨地址是什麼,而後下單,這就至關於起始行裏包含的信息;賣家寄來的包裹裏有你要買的東西,還有使用說明書,那麼這個使用說明書就能夠理解爲首部(header); 你收到的東西就至關於主體(body)了。
雖然這個例子不是很嚴謹,可是也能夠用來造成對這三個部分的感性理解了。
下面來依次討論一下這三個部分。
首先要明確的一點是,請求報文和響應報文因爲目的不一樣,起始行中所包含的信息是有差異的。下面的內容會用 [C] (Client)來表示請求報文中包含的信息, 用 [S] (Server)來表示響應報文中包含的信息。
[C] 方法(method): 客戶端但願服務器對資源作出的動做,例如咱們熟悉的 GET 和 POST 方法。更詳細的內容將在文章後部分討論.
[C] 要請求的資源的URL(request URL): 要請求的資源在服務器上的路徑
[C & S] 版本(version): 客戶端和服務器所使用的HTTP協議的 版本號. 這樣就能夠提示對方本身支持的 HTTP 方法了,防止版本不一樣形成的不兼容問題。 例如: HTTP/1.1 表示這個報文的發送者遵循的是1.1版本的 HTTP 協議.
[S] 狀態碼(status code): 描述服務器根據客戶端的請求進行操做的結果的代碼。例如著名的 404. 網上專門講狀態碼的文章已經不少了,在此不贅述. 更多更詳細的狀態碼描述見 MDN的相應內容.HTTP 響應代碼
[S] 狀態短語(reason-phrase): 和狀態碼對應,是狀態碼所表示的信息的另外一種表示方法,爲了人類能理解,而不是看到狀態碼的時候一會兒反應不過來服這幾個數字表明的信息究竟是什麼。例如和 狀態碼404對應的 Not Found.
下面是兩個具體的例子:
請求報文的起始行 GET /test/hello.txt HTTP/1.1
能夠看到這個字符串包含了用空格分隔的三部分 GET
,/test/hello.txt
和HTTP/1.1
. 則這個部分的含義就是用 GET 方法來請求服務器中路徑是 /test/hello.txt
的資源, 客戶端使用的 HTTP 版本是 1.1.
響應報文的起始行 HTTP/1.0 200 OK
和例1相似的, 能夠看到這個字符串包含了用空格分隔的三部分 HTTP/1.0
,200
和OK
. 含義是: 服務器的 HTTP 版本是 1.0, 對客戶端的請求操做的狀態碼是 200, 表示完成; 同時也用 OK 來講明操做的完成, 便於人類閱讀.
就像以前提到的,首部相似於商品說明書,起到對報文附加說明的做用。它是一些名值對的集合. 例如
Content-length: 19
, 代表這個報文的主體部分的長度是 19. 網上專門講首部字段的文章已經不少了,在此不贅述. 更多更詳細的首部描述見MDN的相應內容. HTTP Headers
首部也能夠分爲幾種顧名思義的類型,包括:通用首部、請求報文專用首部、響應報文專用首部、實體的專用首部等類別。下面舉例來討論一下這幾種類型:
顧名思義,通用首部提供了不管是請求報文仍是響應報文都能使用的首部, 在此僅舉幾個例子來講明:
此類首部用來講明客戶端從何而來,具備的能力,但願獲得的迴應類型以及最重要的不但願獲得的響應的類型等信息, 以便服務器根據它的喜愛回覆數據.
這類首部種類繁多, 在此僅舉幾個例子:
實體由兩部分組成: 實體首部和實體主體.
實體首部提供了實體主體的描述性信息,包括長度、編碼、類型等等等等. 下面舉幾個例子:
Content-Type: 實體主體的類型, 例如 HTML 文檔會被標記爲 text/html; gif 格式的圖片會被標記爲 image/gif. 若是要傳遞的數據類型不止一種, 這種狀況可能會出如今 form 表格中, 用戶可能會一次上傳文字和文件類型的數據, 那麼此時的屬性值會是 Content-Type: multipart/form-data
. 用 multipart 來表示此時傳遞的數據是包含多個主體的.
Content-length: 實體主體的大小
Expires: 實體主體數據的過時時間
Content-Encoding: 實體的處理方式,例如壓縮或者從新編碼
實體主體就是要傳遞的原始數據~~~(網購的商品的主體)~~~, 好比文檔、圖片、音樂等等.
文章只是對 HTTP 報文的一個概覽, 並無進行全面的介紹, 並且爲了便於部份內容的理解, 作了不是徹底恰當的類比.
更多更詳細的內容可見:《HTTP 權威指南》