HTTP報文詳詳詳詳詳詳詳詳解

報文流(The Flow of Messages)

HTTP 報文是在 HTTP 應用程序之間發送的數據塊。這些數據塊以一些文本形式的 元信息(meta-information)開頭,這些信息描述了報文的內容及含義,後面跟着可選的數據部分。

HTTP 使用術語 流入(inbound) 和 流出(outbound) 來描述事務處理(transaction) 的方向。報文流入源端服務器,工作完成之後,會流回用戶的 Agent 代理中。

HTTP 報文會像河水一樣流動。不管是請求報文還是響應報文,所有報文都會向 下游(downstream)流動。所有報文的發送者都在接收者的上游 (upstream)。

報文的語法(Message Syntax)

HTTP 報文是簡單的格式化數據塊。每條報文都包含一條來自客戶端的請求,或者一條來自服務器的響應。它們由三個部分組成:對報文進行描述的 起始行(start line)、包含屬性的 首部(header) 塊,以及可選的包含數據的 主體(body) 部分。

 HTTP-message   = start-line
                  *( header-field CRLF )
                  CRLF
                  [ message-body ]

報文分類與格式

所有的HTTP報文都可以分爲兩類:請求報文(request message) 和 響應報文 (response message)。請求和響應報文的基本報文結構相同。

請求報文的格式:

 <method> <request-URL> <version>  
 <headers>
<entity-body>

響應報文的格式(注意,只有起始行的語法有所不同):

<version> <status> <reason-phrase> 
<headers>

<entity-body>

起始行和首部就是由行分隔的 ASCII 文本。每行都以一個由兩個字符組成的行終止序列作爲結束,其中包括一個回車符(ASCII 碼 13)和一個換行符(ASCII 碼 10)。 這個行終止序列可以寫做 CRLF。

響應報文示例

curl -i www.baidu.com/index.html

HTTP/1.1 200 OK
Server: bfe/1.0.8.18
Date: Wed, 04 Apr 2018 02:39:19 GMT
Content-Type: text/html
Content-Length: 2381
Last-Modified: Mon, 23 Jan 2017 13:27:56 GMT
Connection: Keep-Alive
ETag: "588604dc-94d"
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Pragma: no-cache
Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
Accept-Ranges: bytes

<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新聞</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地圖</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>視頻</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>貼吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登錄</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登錄</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多產品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>關於百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必讀</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意見反饋</a>&nbsp;京ICP證030173號&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>

起始行(Start Lines)

所有的 HTTP 報文都以一個起始行作爲開始。請求報文的起始行說明了要做些什麼。
響應報文的起始行說明發生了什麼。

請求行(Request line)

請求報文請求服務器對資源進行一些操作。請求報文的起始行,或稱爲請求行,包含了一個方法和一個請求 URL,還包含 HTTP 的版本。所有這些字段都由空格符分隔。

響應行(Response line)

響應報文承載了狀態信息和操作產生的所有結果數據,將其返回給客戶端。響應報文的起始行,或稱爲響應行,包含了響應報文使用的 HTTP 版本、數字狀態碼,以 及描述操作狀態的文本形式的原因短語。

方法(Methods)

請求的起始行以方法作爲開始,方法用來告知服務器要做些什麼。比如,在行 “GET /specials/saw-blade.gif HTTP/1.0”中,方法就是 GET。

狀態碼 (Status codes)

在這裏插入圖片描述
狀態碼是在每條響應報文的起始行中返回的。會返回一個數字狀態和一個可讀的狀態。數字碼便於程序進行差錯處理,而原因短語則更便於人們理解。方法是用來告訴服務器做什麼事情的,狀態碼則用來告訴客戶端,發生了什麼事情。

原因短語 (Reason phrases)

原因短語是響應起始行中的最後一個組件。它爲狀態碼提供了文本形式的解釋。比如,在行 HTTP/1.0 200 OK 中,OK 就是原因短語。

版本號(Version numbers)

版本號會以 HTTP/x.y 的形式出現在請求和響應報文的起始行中。

首部

跟在起始行後面的就是零個、一個或多個 HTTP 首部字段。

HTTP 首部字段向請求和響應報文中添加了一些附加信息。本質上來說,它們只是一些名 / 值對的列表。

首部分類

HTTP 規範定義了幾種首部字段。應用程序也可以隨意發明自己所用的首部。HTTP 首部可以分爲以下幾類。

通用首部(General headers):既可以出現在請求報文中,也可以出現在響應報文中。
請求首部(Request headers):提供更多有關請求的信息。
響應首部(Response headers):提供更多有關響應的信息。
實體首部(Entity headers):描述主體的長度和內容,或者資源自身。
擴展首部(Extension headers):規範中沒有定義的新首部。
每個 HTTP 首部都有一種簡單的語法:名字後面跟着冒號( 😃,然後跟上可選的空格,再跟上字段值,最後是一個 CRLF。

實體的主體部分(Entity Bodies)

HTTP 報文的第三部分是可選的實體主體部分。實體的主體是 HTTP 報文的負荷。 就是 HTTP 要傳輸的內容。

HTTP 報文可以承載很多類型的數字數據:圖片、視頻、HTML 文檔、軟件應用程 序、信用卡事務、電子郵件等。

起始行——方法

現在,我們對一些基本 HTTP 方法進行更爲深入的討論。

GET

GET 是最常用的方法。通常用於請求服務器發送某個資源。HTTP/1.1 要求服務器 實現此方法。

HEAD

HEAD 方法與 GET 方法的行爲很類似,但服務器在響應中只返回首部。不會返回實體的主體部分。這就允許客戶端在未獲取實際資源的情況下,對資源的首部進行檢查。使用 HEAD,可以:

在不獲取資源的情況下了解資源的情況(比如,判斷其類型);
通過查看響應中的狀態碼,看看某個對象是否存在;
通過查看首部,測試資源是否被修改了

在這裏插入圖片描述

PUT

與 GET 從服務器讀取文檔相反,PUT 方法會向服務器寫入文檔。有些發佈系統允 許用戶創建 Web 頁面,並用 PUT 直接將其安裝到 Web 服務器上去。

image

PUT 方法的語義就是讓服務器用請求的主體部分來創建一個由所請求的 URL 命名的新文檔,或者,如果那個 URL 已經存在的話,就用這個主體來替代它。

因爲 PUT 允許用戶對內容進行修改,所以很多 Web 服務器都要求在執行 PUT 之前,用密碼登錄。

POST

POST 方法起初是用來向服務器輸入數據的。實際上,通常會用它來支持 HTML 的表單。表單中填好的數據通常會被送給服務器,然後由服務器將其發送到它要去的地方。

POST 用於向服務器發送數據。PUT 用於向服務器上的資源(例如文件)中存儲數據。

TRACE

客戶端發起一個請求時,這個請求可能要穿過防火牆、代理、網關或其他一些應用 程序。每個中間節點都可能會修改原始的 HTTP 請求。TRACE 方法允許客戶端在最終將請求發送給服務器時,看看它變成了什麼樣子。

TRACE 請求會在目的服務器端發起一個“環回”診斷。行程最後一站的服務器會 彈回一條 TRACE 響應,並在響應主體中攜帶它收到的原始請求報文。這樣客戶端就可以查看在所有中間 HTTP 應用程序組成的請求 / 響應鏈上,原始報文是否,以 及如何被毀壞或修改過。

image

TRACE 方法主要用於診斷;也就是說,用於驗證請求是否如願穿過了請求 / 響應 鏈。它也是一種很好的工具,可以用來查看代理和其他應用程序對用戶請求所產生效果。

TRACE 請求中不能帶有實體的主體部分。TRACE 響應的實體主體部分包含了響應服務器收到的請求的精確副本。

OPTIONS

OPTIONS 方法請求 Web 服務器告知其支持的各種功能。可以詢問服務器通常支持 哪些方法,或者對某些特殊資源支持哪些方法。(有些服務器可能只支持對一些特殊 類型的對象使用特定的操作)。

這爲客戶端應用程序提供了一種手段,使其不用實際訪問那些資源就能判定訪問各種資源的最優方式。

image

DELETE

顧名思義,DELETE 方法所做的事情就是請服務器刪除請求 URL 所指定的資源。 但是,客戶端應用程序無法保證刪除操作一定會被執行。因爲 HTTP 規範允許服務 器在不通知客戶端的情況下撤銷請求。

image

擴展方法

HTTP 被設計成字段可擴展的,這樣新的特性就不會使老的軟件失效了。擴展方法指的就是沒有在 HTTP/1.1 規範中定義的方法。服務器會爲它所管理的資源實現一些 HTTP 服務,這些方法爲開發者提供了一種擴展這些 HTTP 服務能力的手段。

首部

首部和方法配合工作,共同決定了客戶端和服務器能做什麼事情。

通用首部——信息性首部

有些首部提供了與報文相關的最基本的信息,它們被稱爲通用首部。

Connection
允許客戶端和服務器指定與請求 / 響應連接有關的選項

Date
提供日期和時間標誌,說明報文是什麼時間創建的

MIME-Version
給出了發送端使用的 MIME 版本

Trailer
如果報文采用了分塊傳輸編碼(chunked transfer encoding)方式,就可 以用這個首部列出位於報文拖掛(trailer)部分的首部集合

Transfer-Encoding
告知接收端爲了保證報文的可靠傳輸,對報文采用了什麼編碼方式

Update
給出了發送端可能想要“升級”使用的新版本或協議

Via
顯示了報文經過的中間節點(代理、網關)

通用首部——緩存首部

Cache-Control
用於隨報文傳送緩存指示

Pragma
另一種隨報文傳送指示的方式,但並不專用於緩存

請求首部——信息性首部
Client-IP
提供了運行客戶端的機器的 IP 地址

From
提供了客戶端用戶的 E-mail 地址

Host
給出了接收請求的服務器的主機名和端口號

Referer
提供了包含當前請求 URI 的文檔的 URL

UA-Color
提供了與客戶端顯示器的顯示顏色有關的信息

UA-CPU
給出了客戶端 CPU 的類型或製造商

UA-Disp
提供了與客戶端顯示器(屏幕)能力有關的信息

UA-OS
給出了運行在客戶端機器上的操作系統名稱及版本

UA-Pixels
提供了客戶端顯示器的像素信息

User-Agent
將發起請求的應用程序名稱告知服務器

請求首部——Accept首部

Accept 首部爲客戶端提供了一種將其喜好和能力告知服務器的方式。

Accept
告訴服務器能夠發送哪些媒體類型

Accept-Charset
告訴服務器能夠發送哪些字符集

Accept-Encoding
告訴服務器能夠發送哪些編碼方式

Accept-Language
告訴服務器能夠發送哪些語言

TE
告訴服務器可以使用哪些擴展傳輸編碼

請求首部——條件請求首部(Conditional request headers)

有時客戶端希望爲請求加上某些限制。

比如,如果客戶端已經有了一份文檔副本, 就希望只在服務器上的文檔與客戶端擁有的副本有所區別時,才請求服務器傳輸文檔。通過條件請求首部,客戶端就可以爲請求加上這種限制,要求服務器在對請求進行響應之前,確保某個條件爲真。

Expect
允許客戶端列出某請求所要求的服務器行爲

If-Match
如果實體標記與文檔當前的實體標記相匹配,就獲取這份文檔

If-Modified-Since
除非在某個指定的日期之後資源被修改過,否則就限制這個請求

If-None-Match
如果提供的實體標記與當前文檔的實體標記不相符,就獲取文檔

If-Range
允許對文檔的某個範圍進行條件請求

If-Unmodified-Since
除非在某個指定日期之後資源沒有被修改過,否則就限制這個請求

Range
如果服務器支持範圍請求,就請求資源的指定範圍

請求首部——安全請求首部

HTTP 本身就支持一種簡單的機制,可以對請求進行質詢 / 響應認證。這種機制要 求客戶端在獲取特定的資源之前,先對自身進行認證,這樣就可以使事務稍微安全 一些。

Authorization
包含了客戶端提供給服務器,以便對其自身進行認證的數據

Cookie
客戶端用它向服務器傳送一個令牌——它並不是真正的安全首部,但確實隱含了安全功能。

Cookie2
用來說明請求端支持的 cookie 版本

請求首部——代理請求首部

隨着因特網上代理的普遍應用,人們定義了幾個首部來協助其更好地工作。

Max-Forward
在通往源端服務器的路徑上,將請求轉發給其他代理或網關的最大次數——與 TRACE 方法一同使用

Proxy-Authorization
與 Authorization 首部相同,但這個首部是在與代理進行認證時使用的

Proxy-Connection
與 Connection 首部相同,但這個首部是在與代理建立連接時使用的

響應首部——信息性首部

Age
(從最初創建開始)響應持續時間

Public
服務器爲其資源支持的請求方法列表

Retry-After
如果資源不可用的話,在此日期或時間重試

Server
服務器應用程序軟件的名稱和版本

Title
對 HTML 文檔來說,就是 HTML 文檔的源端給出的標題

Warning
比原因短語中更詳細一些的警告報文

響應首部——協商首部(Negotiation headers)

如果資源有多種表示方法——比如,如果服務器上有某文檔的法語和德語譯稿, HTTP/1.1 可以爲服務器和客戶端提供對資源進行協商的能力。

Accept-Ranges
對此資源來說,服務器可接受的範圍類型

Vary
服務器查看的其他首部的列表,可能會使響應發生變化;也就是說,這是一個首部列表,服務器會根據這些首部的內容挑選出最適合的資源版本發 送給客戶端

響應首部——安全響應首部(Response security headers)

我們已經看到過安全請求首部了,本質上這裏說的就是 HTTP 的質詢 / 響應認證機制的響應側。

Proxy-Authenticate
來自代理的對客戶端的質詢列表

Set-Cookie
不是真正的安全首部,但隱含有安全功能;可以在客戶端設置一個令牌,
以便服務器對客戶端進行標識

Set-Cookie2
與 Set-Cookie 類似,RFC 2965 Cookie 定義

WWW-Authenticate
來自服務器的對客戶端的質詢列表

實體首部——信息性首部

Allow
列出了可以對此實體執行的請求方法

Location
告知客戶端實體實際上位於何處;用於將接收端定向到資源的(可能是新的)位置(URL)上去

實體首部——內容首部(Content headers)

內容首部提供了與實體內容有關的特定信息,說明了其類型、尺寸以及處理它所需 的其他有用信息。比如,Web 瀏覽器可以通過查看返回的內容類型,得知如何顯示對象。

Content-Base
解析主體中的相對 URL 時使用的基礎 URL

Content-Encoding
對主體執行的任意編碼方式

Content-Language
理解主體時最適宜使用的自然語言

Content-Length
主體的長度或尺寸

Content-Location
資源實際所處的位置

Content-MD5
主體的 MD5 校驗和

Content-Range
在整個資源中此實體表示的字節範圍

Content-Type
這個主體的對象類型

實體首部——實體緩存首部

通用的緩存首部說明了如何或什麼時候進行緩存。實體的緩存首部提供了與被緩存 實體有關的信息——比如,驗證已緩存的資源副本是否仍然有效所需的信息,以及 更好地估計已緩存資源何時失效所需的線索。

ETag
與此實體相關的實體標記

Expires
實體不再有效,要從原始的源端再次獲取此實體的日期和時間

Last-Modified
這個實體最後一次被修改的日期和時間

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章