HTTP报文(转)
之前寫過一篇HTML報文,但是感覺寫完之后還是不懂,最近終于有時間開始看《HTTP權(quán)威指南》,看完之后覺得還是比之前的理解更加深入了,提取HTTP報文出來做個記錄。
HTTP報文分為請求報文(request message)與響應(yīng)報文(response message)。
一、報文的組成部分
一個HTTP報文由3部分組成,分別是:
(1)、起始行(start line)
(2)、首部(header)
(3)、主體(body)
示例:
HTTP/1.0 200 OK //起始行 Content-type:text/plain //首部 Content-length:19 //首部 Hi I'm a message! 主體1.1 請求報文與響應(yīng)報文的格式
請求報文的格式:
<method> <request-UTL> <version> <headers><entity-body>響應(yīng)報文的格式:
<version> <status><reason-phrase> <header><entity-body>留意到請求報文與響應(yīng)報文只是起始行不同。
下面是對格式中各部分的簡要描述
1、方法(method) GET
客戶端希望服務(wù)器對資源執(zhí)行的動作。是一個單獨的詞,比如GET、HEAD或POST。
2、請求的URL(request-URL) www.baidu.com
命名了所有請求資源,或者URL路徑組件的完整URL。如果直接與服務(wù)器進(jìn)行對話,只要URL的路徑組件是資源的絕對路徑,通常就不會有什么問題--服務(wù)器可以假定 自己是URL的主機(jī)/端口。
3、版本(version) HTTP/1.1
報文所使用的HTTP版本,其格式如下:
HTTP/<major>.<minor>
其中主要版本號(major)和次要版本號(minor)都是整數(shù)。
4、狀態(tài)碼(status)
這三個數(shù)字描述了請求過程中所發(fā)生的情況。每個狀態(tài)碼的第一位數(shù)字都用于描述狀態(tài)的一般類別("成功"、"出錯"等)。 200
5、原因短語(reason-phrase)
數(shù)字狀態(tài)碼的可讀版本,包含行終止序列之前的所有文本。原因短語只是給人類看的,它不能說明什么。客戶端依然采用狀態(tài)碼來判斷請求/響應(yīng)是否成功!
例如:HTTP/1.0 200 NOT OK 客戶端依然會當(dāng)請求已成功處理。因為狀態(tài)碼是200。而原因短語只是說明而已,這對于自定義擴(kuò)展?fàn)顟B(tài)碼還是比較有用的。
6、首部(header)
可以有0個或多個首部,每個首部都包含一個名字,后面跟著一個冒號(:),然后是一個可選的空格,接著是一個值,最后是一個CRLF。首部是由一個空行(CRLF)結(jié)束 的,表示了首部列表的結(jié)束和實體主體的開始。
7、實體的主體部分(entity-body)
實體的主體部分包含一個由任意數(shù)據(jù)組成的數(shù)據(jù)塊。并不是所有的報文都包含實體的主體部分。如GET請求就不包含實體。
二、起始行
1、請求行
請求報文的起始行,或稱為請求行。包含了一個方法和一個請求的URL。這個方法描述了服務(wù)器應(yīng)該執(zhí)行的操作,請求URL描述了要對哪個資源執(zhí)行這個方法。請求行中還包含HTTP的版本,用來告知服務(wù)器,客戶端使用的是哪種HTTP版本。如:
GET /info/123.html HTTP/1.1 //方法為GET URL為 /info/123.html HTTP協(xié)議版本為1.11.1方法
下面給出請求報文中方法的列表
方法 描述 是否包含主體
GET 從服務(wù)器獲取一份文檔 否
HEAD 只從服務(wù)器獲取文檔的首部 ? ??否
POST ??向服務(wù)器發(fā)送需要處理的數(shù)據(jù) 是
PUT 將請求的主體部分存儲在服務(wù)器上 ? 是
TRACE 對可能經(jīng)過代理服務(wù)器傳送到服務(wù)器上去的報文進(jìn)行跟蹤 ?否
OPTIONS ?決定可以在服務(wù)器上執(zhí)行哪些方法 ?否
DELETE 從服務(wù)器上刪除一份文檔 ? 否
? 1.2 request-URL
跳過,不說你也知道。
1.3 版本(version)
版本號會以HTTP/x.y 的形式出現(xiàn)在請求和響應(yīng)報文的起始行中。為HTTP應(yīng)用程序提供了一種將自己遵循的協(xié)議版本告知對方的方式。版本號說明了應(yīng)用程序支持的最高HTTP版本。注意,版本號不會被當(dāng)做小數(shù)來處理。因此在比較HTTP版本時,每個數(shù)字都必須單獨做比較,以便確定哪個版本更高。如HTTP/2.22就比HTTP/2.3要高,因為22比3大。
1.4 狀態(tài)碼(status-code)
方法是用來告訴服務(wù)器做什么事情,而狀態(tài)碼則用來告訴客戶端發(fā)生了什么事情。
下面給出狀態(tài)碼的常用分類
整體范圍 ?已定義范圍 分類
100-199 100-101 信息提示
200-299 200-206 ? 成功
300-399 300-305 ? 重定向
400-499 400-415 ? 客戶端錯誤
500-599 500-505 ? 服務(wù)器錯誤
下面再說幾個最常見的狀態(tài)碼。200-OK-成功,請求的所有數(shù)據(jù)都在響應(yīng)主體中。401-Unauthorized(未授權(quán))-需要輸入用戶名和密碼。404-Not Found(未找到)-服務(wù)器無法找到所請求URL對應(yīng)的資源。
1.5原因短語
原因短語是響應(yīng)起始行中的最后一個組件。它為狀態(tài)碼提供了文本形式的解釋。比如在HTTP/1.0 200 OK 中,OK就是原因短語。原因短語和狀態(tài)碼是成對出現(xiàn)的。原因短語是狀態(tài)碼的可讀版本,應(yīng)用程序開發(fā)者將其傳送給用戶,用以說明請求期間發(fā)生了什么情況。客戶端判斷服務(wù)器狀態(tài)依據(jù)的是狀態(tài)碼,與原因短語沒有半毛錢關(guān)系。
三、首部
? HTTP首部字段向請求和響應(yīng)報文中添加了一些附加信息。本質(zhì)上來說,它們只是一些名/值對的列表。比如下面的首部行會向Content-Length首部字段賦值19:
Content-length:19
1、首部分類
HTTP規(guī)范定義了幾種首部字段。應(yīng)用程序也可以隨意發(fā)明自己所用的首部。HTTP首部可以分為以下幾類。
(1)、通用首部:既可以出現(xiàn)在請求報文中,也可以出現(xiàn)在響應(yīng)報文中。
這些是客戶端和服務(wù)器都可以使用的通用首部。可以在客戶端、服務(wù)器和其他應(yīng)用程序之間提供一些非常有用的通用功能。他們像和事佬一樣,,不論報文是何種 類型,都為其提供一些有用的信息。例如不管是構(gòu)建請求報文還是響應(yīng)報文,創(chuàng)建報文的日期時間都是同一個意思,因此提供這類信息的首部對這兩種類型的報文來說 都是通用的。下面用表格的形式給出通用的信息性首部。
通用的信息性首部:
首部 描述
Connection 允許客戶端和服務(wù)器指定與請求/響應(yīng)連接有關(guān)的選項
Date ?提供日期和時間標(biāo)志,說明報文是什么時間創(chuàng)建的
MIME-Version ?給出了發(fā)送端使用的MIME版本
Trailer 如果報文采用了分塊傳輸編碼(chunked transfer encoding)方式,就可以用這個首部列出位于報文拖鞋 (trailer)部分的首部集合。
Transfer-Encoding ?告知接收端為了保證報文的可靠傳輸,對報文采用了什么編碼方式。
Update ?給出了發(fā)送端可能想要"升級"使用的新版本或協(xié)議
Via 顯示了報文經(jīng)過的中間節(jié)點(代理、網(wǎng)關(guān))
通用緩存首部:
首部 描述
Cache-Control ? 用于隨報文傳送緩存指示
Pragma 另一種隨報文傳送指示的方式,但并不專用于緩存
(2)、請求首部:提供更多有關(guān)請求的信息。
請求首部是在請求報文中有意義的首部。用于說明是誰或什么在發(fā)送請求,請求源自何處,或者客戶端的喜好及能力。服務(wù)器可以根據(jù)請求首部給出的客戶端的信 息,試著為客戶端提供更好的響應(yīng)。
請求的信息性首部:
首部 描述
Client-IP 提供了運行客戶端的機(jī)器的IP地址
From ?提供了客戶端用戶的E-mail地址
Host ??給出了接收請求的服務(wù)器的主機(jī)名和端口號
Referer ? 提供了包含當(dāng)前請求URI的文檔的URL
UA-Color ?提供了與客戶端顯示器的顯示顏色有關(guān)的信息
UA-CPU 給出了客戶端CPU的類型或制造商
US-Disp 提供了與客戶端顯示器(屏幕)能力有關(guān)的信息
US-OS ??給出了客戶端顯示器的像素信息
UA-Pixels 提供了客戶端顯示器的像素信息
User-Agent 將發(fā)起請求的應(yīng)用程序名稱告知服務(wù)器(User-Agent)用戶代理,其實不就是瀏覽器嗎
Accept首部為客戶端提供了一種將其喜好和能力告知服務(wù)器的方式,包括他們想要什么,可以使用什么,以及最重要的,他們不想要什么。這樣服務(wù)器就可以根據(jù)這些額外信息,對要發(fā)送的內(nèi)容做出更明智的決定。Accept首部會使連接的兩端都受益。客戶端會得到他們想要的內(nèi)容,服務(wù)器則不會浪費其時間和帶寬來發(fā)送客戶端無法使用的東西。
Accept首部:
首部 描述
Accept ? 告訴服務(wù)器能夠發(fā)送哪些媒體類型
Accept-Charset ??告訴服務(wù)器能夠發(fā)送哪些字符集
Accept-Encoding 告訴服務(wù)器能夠發(fā)送哪些編碼方式
Accept-Language ?告訴服務(wù)器能夠發(fā)送哪些語言
TE ?告訴服務(wù)器可以使用哪些擴(kuò)展傳輸編碼
條件請求首部:
有時客戶端希望為請求加上某些限制。比如客戶端已經(jīng)有了一份副本,就希望只在服務(wù)器上的文檔與客戶端擁有的副本有所區(qū)別時,才請求服務(wù)器傳輸文檔。通過條件請求首部,客戶端就可以加上這種限制,要求服務(wù)器在對請求進(jìn)行相應(yīng)之前,確保某個請求為真。
條件請求首部:
首部 描述
Expect ? 允許客戶端列出某請求所要求的服務(wù)器行為
If-Match 如果實體標(biāo)記與文檔當(dāng)前的實體標(biāo)記相匹配,就或者這份文檔
If-Modified-Since 除非在某個指定的日期之后資源被修改過,否則就限制這個請求
If-Range 允許對文檔的某個范圍進(jìn)行條件請求
If-Unmodified-Since ?除非在某個指定的日期之后資源沒有被修改過,否則就限制這個請求
Range 如果服務(wù)器支持范圍請求,就請求資源的指定范圍
安全請求首部:
HTTP本身就支持一種簡單的機(jī)制,可以對請求進(jìn)行質(zhì)詢/響應(yīng)認(rèn)證。這種機(jī)制要求客戶端在獲取特定的資源之前,先對自身進(jìn)行認(rèn)證,這樣就可以使事務(wù)稍微安全一些。
安全請求首部:
首部 ?描述
Authorization ?包含了客戶端提供給服務(wù)器,以便對其自身進(jìn)行認(rèn)證的數(shù)據(jù)
Cookie ?客戶端用它想服務(wù)器傳送一個令牌-他并不是真正的安全首部,但卻是隱含了安全功能
Cookie2 ? 用來說明請求端支持的cookie版本
代理請求首部:
隨著因特網(wǎng)上代理的普遍應(yīng)用,人們定義了幾個首部來協(xié)助其更好地工作。
代理請求首部:
首部 描述
Max-Forword ?在通往源端服務(wù)器的路徑上,將請求轉(zhuǎn)發(fā)給其他代理或網(wǎng)關(guān)的最大次數(shù)-與TRACE方法一同使用
Proxy-Authorization 與Authorization首部相同,但這個首部是在與代理進(jìn)行認(rèn)證時使用的
Proxy-Connection 與Connection首部相同,但這個首部是在于代理建立連接時使用的
(3)、響應(yīng)首部:提供更多有關(guān)響應(yīng)的信息。
響應(yīng)報文由自己的響應(yīng)首部集。響應(yīng)首部為客戶端提供了一些額外的信息,比如誰在發(fā)送響應(yīng)、響應(yīng)者的功能,甚至與響應(yīng)相關(guān)的一些特殊指令。這些首部有助于客 戶端處理響應(yīng),并在將來發(fā)起更好的請求。
響應(yīng)的信息性首部:
首部 描述
Age (從最初創(chuàng)建開始)響應(yīng)持續(xù)時間
Public ? 服務(wù)器為其資源支持的請求方法列表
Retry-After ? 如果資源不可用的話,再次日期或時間重試
Server ?服務(wù)器應(yīng)用程序軟件的名稱和版本
Title 對HTML文檔來說,就是HTML文檔的源端給出的標(biāo)題
Warning 比原因短語中更詳細(xì)的一些警告報文
協(xié)商首部:如果資源有多種表示方法-比如,如果服務(wù)器上有某文檔的法語和德語譯稿,HTTP/1.1可以為服務(wù)器和客戶端提供對資源進(jìn)行協(xié)商的能力。
協(xié)商首部:
首部 描述
Accept-Ranges 對此資源來說,服務(wù)器可接受的范圍類型
Vary ?服務(wù)器查看的其他首部的列表,可能會使響應(yīng)發(fā)生變化;也就是說,這是一個首部列表,服務(wù)器會根據(jù)這些首部的內(nèi)容挑選出最合適的資源版本 ?發(fā)送給客戶端。
安全響應(yīng)首部:
我們已經(jīng)看到過安全請求首部了,本質(zhì)上這里說的就是HTTP的質(zhì)詢/響應(yīng)認(rèn)證機(jī)制的響應(yīng)側(cè)。
安全響應(yīng)首部:
首部 描述
Proxy-Authenticate 來自代理的對客戶端的質(zhì)詢列表
Set-Cookie 不是真正的安全首部,但隱含有安全功能;可以在客戶端設(shè)置一個令牌,以便服務(wù)器對客戶端進(jìn)行標(biāo)識。
Set-Cookie2 與Set-Cookie類似。
WWW-Authenticate 來自服務(wù)器的對客戶端的質(zhì)詢列表
d、實體首部:描述主體的長度和內(nèi)容,或者資源自身。
有很多首部可以用來描述HTTP報文的負(fù)荷。由于請求和響應(yīng)文本中都可能包含實體部分,所以在這兩種類型的報文中都可能出現(xiàn)這些首部。實體首部提供了有關(guān)實體及 其內(nèi)容的大量信息,從有關(guān)對象類型的信息,到能夠?qū)Y源使用的各種有效的請求方法。總之,實體首部可以告知報文的接收者它在對什么進(jìn)行處理。
實體信息性首部:
首部 描述
Allow 列出了可以對此實體執(zhí)行的請求方法
Location ? 告知客戶端實體實際上位于何處;用于將接收端定向到資源的位置上去
內(nèi)容首部:
內(nèi)容首部提供了與實體內(nèi)容有關(guān)的特定信息,說明了其類型、尺寸以及處理它所需的其他有用信息。比如,Web瀏覽器可以通過查看返回的內(nèi)容類型,得知如何顯示對象。
內(nèi)容首部:
首部 ? 描述
Content-Base ? 解析主體中的相對URL時使用的基礎(chǔ)URL
Content-Encoding ?對主體執(zhí)行的任意編碼方式
Content-Language ?理解主體時最適宜使用的自然語言
Content-Length ?主體的長度或尺寸
Content-Location 資源實際所處的位置
Content-MD5 主體的MD5校驗
Content-Range 在整個資源中此實體表示的字節(jié)范圍
Content-Type ?這個主體的對象模型
實體緩存首部:
通用的緩存首部說明了如何或什么時候進(jìn)行緩存。實體的緩存首部提供了與被緩存實體有關(guān)的信息,比如驗證已緩存的資源副本是否仍然有效所需的信息,以及更好地估計已緩存資源合適失效所需的線索。
實體緩存首部
首部 描述
ETag ??與此實體有關(guān)的實體標(biāo)記
Expires 實體不在有效,要從原始的源端再次獲取此實體的日期和時間
Last-Modified ?這個實體最后一次被修改的日期和時間
e、擴(kuò)展首部:規(guī)范中沒有定義的新首部。
每個HTTP首部都有一種簡單的語法:名字后面跟著冒號(:),然后跟上可選的空格,再跟上字段值。最后是一個回車換行。
2、首部延續(xù)行
將長的首部行分為多行可以提高可讀性,多出來的每行前面至少要有一個空格或制表符(tab)。
HTTP/1.0 200 OK
Content-Type: image/gif
Content-Length: 8572
Server: Test Server
Version 1.0
? 在上面的例子中,響應(yīng)報文里包含了一個Server首部,其值被劃分成了多個延續(xù)行,該首部的完整值為Test Server Version 1.0。
四、實體部分
HTTP的第三部分是可選的實體主體部分,實體的主體是HTTP報文的負(fù)荷。就是HTTP要傳輸?shù)膬?nèi)容。
HTTP報文可以承載很多類型的數(shù)字?jǐn)?shù)據(jù),圖片、視頻、HTML文檔、軟件應(yīng)用程序、信用卡事務(wù)、電子郵件等。
下面來實戰(zhàn)下,我們用瀏覽器打開百度首頁,將HTTP報文實戰(zhàn)解析下:
打開百度的請求報文:
GET / HTTP/1.1 //請求方法為GET,HTTP協(xié)議為1.1 Host: www.baidu.com //URL為www.baidu.com User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0 //用戶代理,也就是瀏覽器了,顯示了瀏覽器的詳細(xì)信息 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 //服務(wù)器能夠發(fā)送的文件類型text/html的意思是HTML文本文檔類型,后面那些查文檔去 Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3 //服務(wù)器能夠發(fā)送的語言 zh-cn為中文,后面那些查文檔去 Accept-Encoding: gzip, deflate //服務(wù)器能夠發(fā)送的編碼格式為gzip,編碼格式不符合瀏覽器會解釋不了 Cookie: BAIDUID=AF6C346B14E94898933E5F858C63F889:FG=1; BDREFER=%7Burl%3A%22http%3A//news.baidu.com/%22%2Cword%3A%22%22%7D; H_PS_PSSID=2097_1464_2133_1944_1788 //cookie,服務(wù)器存儲在客戶端的信息,每次請求都會將服務(wù)器保存在客戶端的cookie一并發(fā)送上服務(wù)器。 Connection: keep-alive //連接,keep-alive保持狀態(tài) Cache-Control: max-age=0 //隨報文傳送緩存指示 cache-control max-age>0 時 直接從游覽器緩存中 提取 max-age<=0 時 向server 發(fā)送http 請求確認(rèn) ,該資源是否有修改 有的話 返回200 ,無的話 返回304.打開百度的響應(yīng)報文:
HTTP/1.1 200 OK //HTTP版本 1.1 狀態(tài)碼200 原因短語OK Date: Tue, 02 Apr 2013 04:27:50 GMT //響應(yīng)的時間日期 Server: BWS/1.0 //服務(wù)器應(yīng)用程序軟件的名稱和版本 BWS/1.0 Content-Length: 4271 //響應(yīng)的主體內(nèi)容的長度為4271個字節(jié) Content-Type: text/html;charset=utf-8 //響應(yīng)類型為HTML文本,編碼類型為utf-8 Cache-Control: private //緩存指示 Expires: Tue, 02 Apr 2013 04:27:50 GMT //實體不在有效,要從原始的源端再次獲取此實體的日期和時間 Content-Encoding: gzip //對主體執(zhí)行的編碼方式為gzip Set-Cookie: H_PS_PSSID=2097_1464_2133_1944_1788; path=/; domain=.baidu.com //設(shè)置cookie,path,domain都是cookie的信息(作用范圍等等) Connection: Keep-Alive //狀態(tài)為保持連接響應(yīng)就牛B了,就是頁面的源代碼:
<!DOCTYPE html><!--STATUS OK--> <html><head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>百度一下,你就知道</title> <style >html,body{height:100%}html{overflow-y:auto}#wrapper{position:relative;_position:;min-height:100%}#content{padding-bottom:100px;text-align:center}#ftCon{height:100px;position:absolute;bottom:44px;text-align:center;width:100%;margin:0 auto;z-index:0;overflow:hidden}#ftConw{width:720px;margin:0 auto}body{font:12px arial;text-align:;background:#fff}body,p,form,ul,li{margin:0;padding:0;list-style:none}body,form,#fm{position:relative}td{text-align:left}img{border:0}a{color:#00c}a:active{color:#f60}#u{color:#999;padding:4px 10px 5px 0;text-align:right}#u a{margin:0 5px}#u .reg{margin:0}#m{width:720px;margin:0 auto}#nv a,#nv b,.btn,#lk{font-size:14px}#fm{padding-left:110px;text-align:left;z-index:1}... 由于內(nèi)容比較多,所以省略后面部分下面來看下一個需要提交表單的請求報文:打開百度的登錄窗口,填寫完信息后提交是的請求報文POST信息為:
callback parent.bdPass.api.login._postCallback charset utf-8 codestring index 0 isPhone false loginType 1 mem_pass on password 123 ppui_logintime 13905 safeflg 0 staticpage http://www.baidu.com/cache/user/html/jump.html token d0de247f344d33dbb9692491dc5574cd tpl mn u username 123@qwe.com verifycode總結(jié)
- 上一篇: Julia语言:让高性能科学计算人人可用
- 下一篇: 什么牌子的手机POS机好?手机POS机盘