HTTP報文詳解

文章同步於 Github blog

報文流(The Flow of Messages)

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

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

HTTP 報文會像河水同樣流動。不論是請求報文仍是響應報文,全部報文都會向 下游(downstream)流動。全部報文的發送者都在接收者的上游 (upstream)。git

報文的語法(Message Syntax)

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

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

報文分類與格式

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

請求報文的格式:瀏覽器

<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 的版本。全部這些字段都由空格符分隔。cookie

響應行(Response line)

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

方法(Methods)

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

狀態碼 (Status codes)

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

總體範圍 已定義範圍 分類
100 ~ 199 100 ~ 101 信息提示
200~299 200~206 成功
300 ~ 399 300 ~ 305 重定向
400 ~ 499 400 ~ 415 客戶端錯誤
500 ~ 599 500 ~ 505 服務器錯誤

緣由短語 (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,能夠:

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

image

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

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

參考

相關文章
相關標籤/搜索