一、簡介
從web客戶端發往web服務器的http報文稱爲請求報文(request message),從服務器發往客戶端的報文稱爲響應報文(response message),此外沒有其它類型的http報文。
http請求和響應報文的格式很類似,都包括以下3個部分:
-
起始行(start line)
報文的第一行就是起始行,在請求報文中用來說明要做些什麼,在響應報文中說明出現了什麼情況。 -
首部字段(header)
起始後面有零個或多個首部字段。每個首部字段都包含一個名字和一個值,爲了便於解析,兩者之間用冒號(:)來分隔。首部以一個空格結束。添加一個首部字段和添加新行一樣簡單。 -
主體(body)
空行之後就是可選的報文主體了,其中包含了所有類型的數據。請求主體中包括了要發送給web服務器的數據;響應主體中裝載了要返回給客戶端的數據。起始行和首部都是文本形式且都是結構化的,而主體則不同,主體中可以包含任意的二進制數據(比如圖片、視頻、音軌、軟件程序)。當然,主體中也可以包含文本。
二、語法
請求報文與響應報文只有起始行的語法有所不同。
1、請求報文:
<method> <request-URL> <version>
<headers>
<entity-body>
如:
GET /test/hi.txt HTTP/1.1
Accept: text/*
Host: www.test.com
2、響應報文:
<version> <status> <reason-phrase>
<headers>
<entity-body>
如:
HTTP/1.1 200 OK
Content-type: text/plain
Content-length: 19
Hi! I'm a message!
三、抓包
我們常用的HTTP抓包工具有如fiddler、firebug等,大家根據自己的喜好選擇自己的工具。
如下是我使用firebug抓取到的一個http請求及響應包:
四、首部
HTTP首部字段可以分爲如下幾類:通用首部、請求首部、響應首部、實體首部、擴展首部。
每個HTTP首部都有一種簡單的語法:名字後面跟着冒號(:),然後跟上可選空格,再跟上字段值,最後是一個CRLF。
1、通用首部
有些首部提供了與報文相關的最基本信息,它們被稱爲通用首部。客戶端和服務器都可以使用這些通用首部。
首部 | 描述 | 舉例 |
---|---|---|
Connection | 允許客戶端和服務器端指定與請求/響應連接有關的選項 | Connection: close |
Date | 報文創建的日期和時間 | Date: Tue, 3 Oct 1974 02:16:00 GMT |
MIME-Version | 給出了發送端使用的MIME版本 | MIME-Version: 1.0 |
Trailer | 說明報文拖掛中提供了哪些首部 | Trailer: Content-Length |
Trailer-Encoding | 告知接收端爲了保證報文的可選傳輸,對報文采用什麼編碼方式 | Trailer-Encoding: chunked |
Update | 給出了發送端可能想要“升級”使用的新版本或協議 | |
Via | 顯示了報文經過的中間節點(代理、網關) | Via: joes-hardware.com (Joes-Server/1.0) |
Cache-Control | 給出了與某個對象可緩存性有關的緩存特有指令 | Cache-Control: no-cache |
Pragma | 用於隨報文傳送一些指令,但並不專用於緩存 | Pragma: no-cache |
2、請求首部
請求首部是隻在請求報文中有意義的首部。用於說明是誰或什麼在發送請求、請求源自何處,或者客戶端的喜好能力、服務器可以根據請求首部給出的客戶端信息,試着爲客戶端提供更好的響應。
以下將對請求首部進行分類介紹:
- 請求的信息性首部
首部 | 描述 | 舉例 |
---|---|---|
Client-IP | 提供了運行客戶端的機器的IP地址 | Client-ip: 209.1.33.49 |
From | 提供了客戶端用戶的E-mail地址 | From: [email protected] |
Host | 提供了客戶端想要訪問的那臺機器的因特網主機名和端口號 | Host: www.test.com:80 |
Referer | 使服務器知道客戶端是從哪裏獲得其請求的URL | Referer: http://www.test.com/index.html |
UA-Color | 客戶端顯示器的顯示顏色有關的信息 | UA-Color: color8 |
UA-CPU | 客戶端CPU的類型或製造商 | UA-CPU: x86 |
UA-Disp | 客戶端顯示器能力有關的信息 | UA-Disp: 640, 480, 8 |
UA-OS | 客戶端的操作系統名稱及版本 | UA-OS: Windows 95 |
UA-Pixels | 顯示器的像素信息 | UA-Pixels: 640 x 480 |
User-Agent | 發起請求的應用程序名稱 | User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0) |
- Accept首部
Accept首部爲客戶端提供了一種將其喜好和能力告知服務器的方式,包括它們想要什麼,可以使用什麼,以及最重要的,它們不想要什麼。這樣,服務器就可以根據這些額外信息,對要發送的內容做出更明智的決定。Accept首部會使連接的兩端都受益。客戶端會得到它們想要的內容,服務器則不會浪費其時間和帶寬來發送客戶端無法使用的東西。
首部 | 描述 | 舉例 |
---|---|---|
Accept | 告訴服務器能夠發送哪些媒體類型 | Accept: text/*, image/* |
Accept-Charset | 告訴服務器能夠發送哪些字符集 | Accept-Charset: iso-latin-1 |
Accept-Encoding | 告訴服務器能夠發送哪些編碼方式 | Accept-Encoding: compress;q=0.5, |
Accept-Language | 告訴服務器能夠發送哪些語言 | Accept-Language: en; q=0.7, en-gb;q=0.5 |
TE | 告訴服務器可以使用哪些擴展傳輸編碼 | TE: chunked |
- 條件請求首部
有時客戶端希望爲請求加上某些限制。比如,如果客戶端已經有了一份文檔副本,就希望只有服務器上的文檔與客戶端擁有的副本有所區別時,才請求服務器傳輸文檔。通過條件請求首部,客戶端就可以爲請求加上這種限制,要求服務器在對請求進行響應之前,確保某個條件爲真。
首部 | 描述 | 舉例 |
---|---|---|
Expect | 允許客戶端列出某請求所要求的服務器行爲 | Expect: 100-continue |
If-Match | 如果實體標記與文檔當前的實體標記相匹配,就獲取這份文檔 | If-Match: “11e92a-457b-31345aa” |
If-Modified-Since | 除非在某個指定的日期之後資源被修改過,否則就限制這個請求 | If-Modified-Since: Thu, 03 Oct 1997 17:15:00 GMT |
If-None-Match | 如果提供的實體標記與當前文檔的實體標記不相符,就獲取文檔 | If-None-Match: “11e92a-457b-31345aa” |
If-Range | 允許對文檔的某個範圍進行條件請求 | If-Range: “11e92a-457b-31345aa” |
If-Unmodified-Since | 除非在某個指定日期之後資源沒有被修改過,否則就限制這個請求 | If-Unmodified-Since: Thu, 03 Oct 1997 17:15:00 GMT |
Range | 如果服務器支持範圍請求,就請求資源的指定範圍 | Range: 500-1500 |
- 安全請求首部
HTTP本身就支持一種簡單的機制,可以對請求進行質詢/響應認證。這種機制要求客戶端在獲取特定的資源之前,先對自身進行認證,這樣就可以使事務稍微安全一些。
首部 | 描述 | 舉例 |
---|---|---|
Authorization | 包含了客戶端提供給服務器,以便對其自身進行認證的數據(否則會收到401錯誤) | Authorization: Basic gfujhver9854fcjyf54wfku6 |
Cookie | 客戶端用它向服務器傳送一個令牌(它並不是一個真正的安全首部,但確實隱含了安全功能) | Cookie: ink=ghfdytfuyt76dyc76ru5rju7ft76 |
Cookie2 | 用來說明請求端支持的cookie版本 | Cookie2: $version=“1” |
- 代理請求首部
隨着因特網上代理的普遍應用,人們定義了幾個首部來協助其更好地工作。
首部 | 描述 | 舉例 |
---|---|---|
Max-Forward | 這個首部只能和TRACE方法一起使用,以指定請求所經過的代理或其它中間節點的最大數目 | Max-Forward: 5 |
Proxy-Authorization | 與Authorization首部相同,但這個首部是在與代理進行認證時使用的 | Proxy-Authorization: Basic gfujhver9854fcjyf54wfku6 |
Proxy-Connection | 與Connection首部相同,但這個首部是在與代理建立連接時使用的 | Proxy-Connection: close |
3、響應首部
響應首部爲客戶端提供了一些額外信息,比如誰在發送響應、響應者的功能,甚至與響應相差的一些特殊指令。這些首部有助於客戶端處理響應,並在將來發起更好的請求。
- 響應的信息首部
首部 | 描述 | 舉例 |
---|---|---|
Age | (從最初創建開始)響應持續時間,以秒爲單位 | Age: 60 |
Public | 服務器爲其資源支持的請求方法列表 | Public: OPTIONS, GET, HEAD, TRACE, POST |
Retry-After | 如果資源不可用的話,在此日期或時間重試(可以與503狀態碼配合使用) | Retry-After: Thu, 3 Oct 1997 17:15:00 GMT |
Server | 服務器應用程序的名稱和版本 | Server: Websitepro/1.1s (s/n wpo-07d0) |
Title | 對HTML文檔來說,就是HTML文檔的源端給出的標題 | Title: decument-title |
Warning | 比原因短語中更詳細的一些警告報文 | Warning: 113 |
- 協商首部
如果資源有多種表示方法——比如,如果服務器上有某文檔的法語和德語稿,HTTP/1.1可以爲服務器和客戶端提供對資源進行協商的能力。
首部 | 描述 | 舉例 |
---|---|---|
Accept-Ranges | 服務器可以接受對資源的哪個範圍類型進行訪問 | Accept-Ranges: bytes |
Vary | 服務器通過Vary首部來通知客戶端,有服務器端的協商中會使用哪些來自客戶端請求的首部。它的值是一個首部列表,服務器去查看這些首部,以確定將什麼內容作爲響應發回給客戶端 | Vary: User-Agent |
- 安全響應首部
我們已經看到過安全請求首部了,本質上這裏說的就是HTTP的質詢/響應認證機制的響應側。
首部 | 描述 | 舉例 |
---|---|---|
Proxy-Authenticate | 來自代理的對客戶端的質詢列表 | Proxy-Authenticate: Basic realm=“Super Secret Corporate FinancialDocuments” |
Set-Cookie | Set-Cookie首部是Cookie首部的搭檔。(不是真正的安全首部,但隱含有安全功能;可以在客戶端設置一個令牌,以便服務器對客戶端進行標識) | Set-Cookie: private_id=519; secure |
Set-Cookie2 | 與Set-Cookie類似,是對Set-Cookie首部的擴展,RFC 2965 Cookie定義 | Set-Cookie2: ID=“23453”; Domain=".test.com" |
WWW-Authenticate | 來自服務器的對客戶端的質詢列表(用於401響應) | WWW-Authenticate: Basic realm=“Your Private Travel Profile” |
4、實體首部
有很多首部可以用來描述HTTP報文的負荷。由於請求和響應報文中都可能包含實體部分,所以在這兩種類型的報文中都有可能出現這些首部。
實體首部提供了有關實體及其內容的大量信息。
- 實體的信息首部
首部 | 描述 | 舉例 |
---|---|---|
Allows | 列出了可以對此實體執行的請求方法 | Allows: GET, HEAD |
Location | 告知客戶端實體實際上位於何處;用於將接收端定向到資源的(可能是新的)位置(URL)上去 | Location: http://www.test.com |
- 內容首部
內容首部提供了與實體內容有關的特定信息,說明了其類型、尺寸以及處理它所需的其它有用信息。
首部 | 描述 | 舉例 |
---|---|---|
Connect-Base | 解析主體中的相對URL時使用的基礎URL | Connect-Base: http://www.test.com/ |
Connect-Encoding | 對主體執行的任意編碼方式(告知客戶端,服務器對對象執行過哪種或哪些類型的編碼) | Connect-Encoding: gzip |
Connect-Language | 理解主體時最適宜使用的自然語言 | Connect-Language: en |
Connect-Length | 主體的長度或尺寸 | Connect-Length: 2434 |
Connect-Location | 資源實際所在的位置 | Connect-Location: http://www.test.com/index.html |
Connect-MD5 | 主體的MD5校驗和 | Connect-MD5: jygi2uy3pi1guy64uyfg== |
Connect-Range | 在整個資源中此實體列示的範圍 | Connect-Range: bytes 500-999 / 5400 |
Connect-Type | 這個主體的對象類型 | Connect-Type: text/html; charset=iso-latin-1 |
- 實體緩存首部
通用的緩存首部說明了如何或什麼時候進行緩存。實體的緩存首部提供了與被緩存實體有關的信息——比如,驗證已緩存的資源副本是否仍然有效所需的信息,以及更好地估計已緩存資源何時失效所需的線索。
首部 | 描述 | 舉例 |
---|---|---|
ETag | 與此實體相差的實體標記 | ETag: W/“11e92a-457b-3134b6aa” |
Expires | 實體不再有效,要從原始的源端再次獲取此實體的日期和時間 | Expires: Thu, 03 Oct 1997 17:15:00 GMT |
Last-Modified | 這個實體最後一次被修改的日期和時間 | Last-Modified: Thu, 03 Oct 1997 17:15:00 GMT |
參考
《HTTP權威指南》 David Gourley, Brian Totty, Marjorie Sayer, Sailu Reddy, Ansbu Aggarwal 著 陳涓 趙振平 譯
RFC:https://tools.ietf.org/html/rfc2616(查看第14章)
W3C:https://www.w3.org/Protocols/rfc2616/rfc2616.html(查看第14章)