HTTP報文


  之前寫過一篇HTML報文,但是感覺寫完之后還是不懂,最近終於有時間開始看《HTTP權威指南》,看完之后覺得還是比之前的理解更加深入了,提取HTTP報文出來做個記錄。

  HTTP報文分為請求報文(request message)與響應報文(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 請求報文與響應報文的格式

  請求報文的格式:

<method> <request-UTL> <version>
<headers>

<entity-body>

  響應報文的格式:

<version> <status><reason-phrase>
<header>

<entity-body>

  留意到請求報文與響應報文只是起始行不同。

  下面是對格式中各部分的簡要描述

  1、方法(method)  GET

    客戶端希望服務器對資源執行的動作。是一個單獨的詞,比如GET、HEAD或POST。

  2、請求的URL(request-URL)  www.baidu.com

    命名了所有請求資源,或者URL路徑組件的完整URL。如果直接與服務器進行對話,只要URL的路徑組件是資源的絕對路徑,通常就不會有什么問題--服務器可以假定   自己是URL的主機/端口。

  3、版本(version)  HTTP/1.1

    報文所使用的HTTP版本,其格式如下:

    HTTP/<major>.<minor>

    其中主要版本號(major)和次要版本號(minor)都是整數。  

  4、狀態碼(status)

    這三個數字描述了請求過程中所發生的情況。每個狀態碼的第一位數字都用於描述狀態的一般類別("成功"、"出錯"等)。  200

  5、原因短語(reason-phrase)

    數字狀態碼的可讀版本,包含行終止序列之前的所有文本。原因短語只是給人類看的,它不能說明什么。客戶端依然采用狀態碼來判斷請求/響應是否成功!

    例如:HTTP/1.0 200 NOT OK 客戶端依然會當請求已成功處理。因為狀態碼是200。而原因短語只是說明而已,這對於自定義擴展狀態碼還是比較有用的。

  6、首部(header)

    可以有0個或多個首部,每個首部都包含一個名字,后面跟着一個冒號(:),然后是一個可選的空格,接着是一個值,最后是一個CRLF。首部是由一個空行(CRLF)結束   的,表示了首部列表的結束和實體主體的開始。

  7、實體的主體部分(entity-body)

    實體的主體部分包含一個由任意數據組成的數據塊。並不是所有的報文都包含實體的主體部分。如GET請求就不包含實體。

二、起始行

  1、請求行

  請求報文的起始行,或稱為請求行。包含了一個方法和一個請求的URL。這個方法描述了服務器應該執行的操作,請求URL描述了要對哪個資源執行這個方法。請求行中還包含HTTP的版本,用來告知服務器,客戶端使用的是哪種HTTP版本。如:

  GET /info/123.html HTTP/1.1    //方法為GET    URL為 /info/123.html    HTTP協議版本為1.1

  1.1方法

  下面給出請求報文中方法的列表

方法        描述                    是否包含主體
GET     從服務器獲取一份文檔                   否
HEAD    只從服務器獲取文檔的首部                    否
POST      向服務器發送需要處理的數據               是
PUT     將請求的主體部分存儲在服務器上               是
TRACE    對可能經過代理服務器傳送到服務器上去的報文進行跟蹤     否
OPTIONS   決定可以在服務器上執行哪些方法               否
DELETE   從服務器上刪除一份文檔                   否

   1.2 request-URL

  跳過,不說你也知道。

  1.3 版本(version)

  版本號會以HTTP/x.y 的形式出現在請求和響應報文的起始行中。為HTTP應用程序提供了一種將自己遵循的協議版本告知對方的方式。版本號說明了應用程序支持的最高HTTP版本。注意,版本號不會被當做小數來處理。因此在比較HTTP版本時,每個數字都必須單獨做比較,以便確定哪個版本更高。如HTTP/2.22就比HTTP/2.3要高,因為22比3大。

  1.4 狀態碼(status-code)

  方法是用來告訴服務器做什么事情,而狀態碼則用來告訴客戶端發生了什么事情。

  下面給出狀態碼的常用分類

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

  下面再說幾個最常見的狀態碼。200-OK-成功,請求的所有數據都在響應主體中。401-Unauthorized(未授權)-需要輸入用戶名和密碼。404-Not Found(未找到)-服務器無法找到所請求URL對應的資源。

  1.5原因短語

  原因短語是響應起始行中的最后一個組件。它為狀態碼提供了文本形式的解釋。比如在HTTP/1.0 200 OK 中,OK就是原因短語。原因短語和狀態碼是成對出現的。原因短語是狀態碼的可讀版本,應用程序開發者將其傳送給用戶,用以說明請求期間發生了什么情況。客戶端判斷服務器狀態依據的是狀態碼,與原因短語沒有半毛錢關系。

三、首部

   HTTP首部字段向請求和響應報文中添加了一些附加信息。本質上來說,它們只是一些名/值對的列表。比如下面的首部行會向Content-Length首部字段賦值19:

    Content-length:19

  1、首部分類

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

    (1)、通用首部:既可以出現在請求報文中,也可以出現在響應報文中。

      這些是客戶端和服務器都可以使用的通用首部。可以在客戶端、服務器和其他應用程序之間提供一些非常有用的通用功能。他們像和事佬一樣,,不論報文是何種      類型,都為其提供一些有用的信息。例如不管是構建請求報文還是響應報文,創建報文的日期時間都是同一個意思,因此提供這類信息的首部對這兩種類型的報文來說      都是通用的。下面用表格的形式給出通用的信息性首部。

    通用的信息性首部:

首部           描述
Connection        允許客戶端和服務器指定與請求/響應連接有關的選項
Date            提供日期和時間標志,說明報文是什么時間創建的
MIME-Version       給出了發送端使用的MIME版本
Trailer          如果報文采用了分塊傳輸編碼(chunked transfer encoding)方式,就可以用這個首部列出位於報文拖鞋 (trailer)部分的首部集合。
Transfer-Encoding     告知接收端為了保證報文的可靠傳輸,對報文采用了什么編碼方式。
Update          給出了發送端可能想要"升級"使用的新版本或協議
Via            顯示了報文經過的中間節點(代理、網關)

通用緩存首部:

首部           描述
Cache-Control       用於隨報文傳送緩存指示
Pragma          另一種隨報文傳送指示的方式,但並不專用於緩存

    (2)、請求首部:提供更多有關請求的信息。

      請求首部是在請求報文中有意義的首部。用於說明是誰或什么在發送請求,請求源自何處,或者客戶端的喜好及能力。服務器可以根據請求首部給出的客戶端的信      息,試着為客戶端提供更好的響應。

請求的信息性首部:
首部              描述
Client-IP           提供了運行客戶端的機器的IP地址
From              提供了客戶端用戶的E-mail地址
Host               給出了接收請求的服務器的主機名和端口號
Referer             提供了包含當前請求URI的文檔的URL
UA-Color            提供了與客戶端顯示器的顯示顏色有關的信息
UA-CPU            給出了客戶端CPU的類型或制造商
US-Disp           提供了與客戶端顯示器(屏幕)能力有關的信息
US-OS             給出了客戶端顯示器的像素信息
UA-Pixels           提供了客戶端顯示器的像素信息
User-Agent          將發起請求的應用程序名稱告知服務器(User-Agent)用戶代理,其實不就是瀏覽器嗎

  Accept首部為客戶端提供了一種將其喜好和能力告知服務器的方式,包括他們想要什么,可以使用什么,以及最重要的,他們不想要什么。這樣服務器就可以根據這些額外信息,對要發送的內容做出更明智的決定。Accept首部會使連接的兩端都受益。客戶端會得到他們想要的內容,服務器則不會浪費其時間和帶寬來發送客戶端無法使用的東西。

Accept首部:
首部            描述
Accept            告訴服務器能夠發送哪些媒體類型
Accept-Charset       告訴服務器能夠發送哪些字符集
Accept-Encoding     告訴服務器能夠發送哪些編碼方式
Accept-Language      告訴服務器能夠發送哪些語言
TE             告訴服務器可以使用哪些擴展傳輸編碼

  條件請求首部:

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

條件請求首部:
首部            描述
Expect           允許客戶端列出某請求所要求的服務器行為
If-Match         如果實體標記與文檔當前的實體標記相匹配,就或者這份文檔
If-Modified-Since     除非在某個指定的日期之后資源被修改過,否則就限制這個請求
If-Range         允許對文檔的某個范圍進行條件請求
If-Unmodified-Since    除非在某個指定的日期之后資源沒有被修改過,否則就限制這個請求
Range          如果服務器支持范圍請求,就請求資源的指定范圍

安全請求首部:

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

安全請求首部:
首部            描述
Authorization        包含了客戶端提供給服務器,以便對其自身進行認證的數據
Cookie           客戶端用它想服務器傳送一個令牌-他並不是真正的安全首部,但卻是隱含了安全功能
Cookie2           用來說明請求端支持的cookie版本

代理請求首部:

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

代理請求首部:
首部            描述
Max-Forword       在通往源端服務器的路徑上,將請求轉發給其他代理或網關的最大次數-與TRACE方法一同使用
Proxy-Authorization   與Authorization首部相同,但這個首部是在與代理進行認證時使用的
Proxy-Connection    與Connection首部相同,但這個首部是在於代理建立連接時使用的

    (3)、響應首部:提供更多有關響應的信息。

      響應報文由自己的響應首部集。響應首部為客戶端提供了一些額外的信息,比如誰在發送響應、響應者的功能,甚至與響應相關的一些特殊指令。這些首部有助於客     戶端處理響應,並在將來發起更好的請求。

響應的信息性首部:
首部          描述
Age          (從最初創建開始)響應持續時間
Public          服務器為其資源支持的請求方法列表
Retry-After       如果資源不可用的話,再次日期或時間重試
Server         服務器應用程序軟件的名稱和版本
Title          對HTML文檔來說,就是HTML文檔的源端給出的標題
Warning        比原因短語中更詳細的一些警告報文

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

協商首部:
首部         描述
Accept-Ranges    對此資源來說,服務器可接受的范圍類型
Vary          服務器查看的其他首部的列表,可能會使響應發生變化;也就是說,這是一個首部列表,服務器會根據這些首部的內容挑選出最合適的資源版本            發送給客戶端。

安全響應首部:

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

安全響應首部:
首部 描述
Proxy-Authenticate 來自代理的對客戶端的質詢列表
Set-Cookie 不是真正的安全首部,但隱含有安全功能;可以在客戶端設置一個令牌,以便服務器對客戶端進行標識。
Set-Cookie2 與Set-Cookie類似。
WWW-Authenticate 來自服務器的對客戶端的質詢列表

    d、實體首部:描述主體的長度和內容,或者資源自身。

    有很多首部可以用來描述HTTP報文的負荷。由於請求和響應文本中都可能包含實體部分,所以在這兩種類型的報文中都可能出現這些首部。實體首部提供了有關實體及    其內容的大量信息,從有關對象類型的信息,到能夠對資源使用的各種有效的請求方法。總之,實體首部可以告知報文的接收者它在對什么進行處理。

實體信息性首部:
首部        描述
Allow        列出了可以對此實體執行的請求方法
Location       告知客戶端實體實際上位於何處;用於將接收端定向到資源的位置上去

內容首部:

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

內容首部:
首部              描述
Content-Base         解析主體中的相對URL時使用的基礎URL
Content-Encoding       對主體執行的任意編碼方式
Content-Language      理解主體時最適宜使用的自然語言
Content-Length        主體的長度或尺寸
Content-Location      資源實際所處的位置
Content-MD5        主體的MD5校驗
Content-Range       在整個資源中此實體表示的字節范圍
Content-Type         這個主體的對象模型

實體緩存首部:

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

實體緩存首部
首部        描述
ETag        與此實體有關的實體標記
Expires      實體不在有效,要從原始的源端再次獲取此實體的日期和時間
Last-Modified   這個實體最后一次被修改的日期和時間

    e、擴展首部:規范中沒有定義的新首部。

    每個HTTP首部都有一種簡單的語法:名字后面跟着冒號(:),然后跟上可選的空格,再跟上字段值。最后是一個回車換行。

  2、首部延續行

    將長的首部行分為多行可以提高可讀性,多出來的每行前面至少要有一個空格或制表符(tab)。

HTTP/1.0 200 OK
Content-Type: image/gif
Content-Length: 8572
Server: Test Server
Version 1.0

     在上面的例子中,響應報文里包含了一個Server首部,其值被划分成了多個延續行,該首部的完整值為Test Server Version 1.0。

四、實體部分

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

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

  下面來實戰下,我們用瀏覽器打開百度首頁,將HTTP報文實戰解析下:

  打開百度的請求報文:

GET / HTTP/1.1                //請求方法為GET,HTTP協議為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    //用戶代理,也就是瀏覽器了,顯示了瀏覽器的詳細信息
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8        //服務器能夠發送的文件類型text/html的意思是HTML文本文檔類型,后面那些查文檔去
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3                //服務器能夠發送的語言 zh-cn為中文,后面那些查文檔去
Accept-Encoding: gzip, deflate                            //服務器能夠發送的編碼格式為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,服務器存儲在客戶端的信息,每次請求都會將服務器保存在客戶端的cookie一並發送上服務器。
Connection: keep-alive    //連接,keep-alive保持狀態
Cache-Control: max-age=0    //隨報文傳送緩存指示    cache-control max-age>0 時 直接從游覽器緩存中 提取 max-age<=0 時 向server 發送http 請求確認 ,該資源是否有修改 有的話 返回200 ,無的話 返回304.

  打開百度的響應報文:

HTTP/1.1 200 OK        //HTTP版本 1.1    狀態碼200 原因短語OK
Date: Tue, 02 Apr 2013 04:27:50 GMT    //響應的時間日期
Server: BWS/1.0        //服務器應用程序軟件的名稱和版本 BWS/1.0
Content-Length: 4271    //響應的主體內容的長度為4271個字節
Content-Type: text/html;charset=utf-8    //響應類型為HTML文本,編碼類型為utf-8
Cache-Control: private        //緩存指示
Expires: Tue, 02 Apr 2013 04:27:50 GMT    //實體不在有效,要從原始的源端再次獲取此實體的日期和時間
Content-Encoding: gzip        //對主體執行的編碼方式為gzip
Set-Cookie: H_PS_PSSID=2097_1464_2133_1944_1788; path=/; domain=.baidu.com    //設置cookie,path,domain都是cookie的信息(作用范圍等等)
Connection: Keep-Alive    //狀態為保持連接

  響應就牛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}...
由於內容比較多,所以省略后面部分

  下面來看下一個需要提交表單的請求報文:打開百度的登錄窗口,填寫完信息后提交是的請求報文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    

  可以看到在表單提交的請求賬號密碼都在請求報文的實體里面傳送上服務器了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM