目錄
一、HTTP報文
1.請求報文
2.回應報文
二、4種HTTP首部欄位型別
1.通用首部欄位 ( General Header Fields )
a. Cache-Control指令
b.Connection欄位
c.Pragma欄位
d. max-age與s-maxage指令
2.請求首部欄位 ( Request Header Fields )
a.Accept欄位
b.Host欄位
3.回應首部欄位( Response Header Fields )
a.ETag欄位
4.物體首部欄位( Entity Header Fields )
5.非HTTP/1.1首部欄位
a.Set-Cookie欄位
b.Cookie欄位
三、報文主體和物體主體
四、內容編碼(壓縮)
五、分塊傳輸編碼(分割發送)
六、多部分物件集合(含有多型別物體)
七、范圍請求(中斷后繼續下載)
八、內容協商
一、HTTP報文
用于 HTTP 協議互動的資訊被稱為 HTTP 報文,請求端(客戶端)的 HTTP 報文叫做請求報文,回應端(服務器端)的叫做回應報文, HTTP 報文本身是由多行(用 CR + LF 作換行符,windows端即\r\n)資料構成的字串文本,

HTTP報文大致可分為報文首部和報文主體兩塊,兩者由最初出現的空行( CR + LF )來劃分,通常,并不一定要有報文主體,
1.請求報文

請求報文的報文首部由請求行、首部欄位及其他組成,
- 請求行:包含請求方法、請求URI、HTTP版本,
- 首部欄位:包含請求首部欄位、通用首部欄位、物體首部欄位三部分,
- 其他:可能包含HTTP的RFC里未定義的首部(如Cookie等),
eg:請求報文的報文首部資訊如下:
GET / HTTP/1.1
Host: hackr.jp
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/=>20100101 Firefox/13.0
Accept: text/html, application/xhtml+xml, application/xml; q=0.9, =>*/*; q=0.8
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
If-Modified-Since: Fri, 31 Aug 2007 02:02:20 GMT
If-None-Match: "45bae1-16a-46d776ac"
Cache-Control: max-age=0
2.回應報文

回應報文的報文首部由狀態行、首部欄位及其他組成,
- 狀態行:包含表明回應結果的狀態碼、原因短語、HTTP版本,
- 首部欄位:包含回應首部欄位、通用首部欄位、物體首部欄位三部分,
- 其他:可能包含HTTP的RFC里未定義的首部(如Cookie等),
eg:回應報文的報文首部資訊如下:
HTTP/1.1304 Not Modified
Date: Thu, 07 Jun 2012 07:21:36 GMT
Server: Apache
Connection: close
Etag: "45bae1-16a-46d776ac"
二、4種HTTP首部欄位型別
HTTP首部欄位是構成 HTTP 報文的要素之一,在客戶端與服務器之間以 HTTP 協議進行通信的程序中,無論是請求還是回應都會使用首部欄位,它能起到傳遞額外重要資訊的作用,
使用首部欄位是為了給瀏覽器和服務器提供報文主體大小、所使用的語言、認證資訊等內容,HTTP首部欄位是由首部欄位名和欄位值構成的,中間用冒號":"分隔,HTTP首部欄位根據實際用途被分為以下 4 種型別:
1.通用首部欄位 ( General Header Fields )
請求報文和回應報文兩方都會使用的首部,
a. Cache-Control指令
Cache-Control指令可用于請求和回應時,按請求和回應分類如下:
很容易把 no- cache 誤解成為不快取 , 但事實上 no- cache 代表不快取過期的資源 , 快取會向源服務器進行有效期確認后處理資源 , 也許稱為 do-not-serve-from-cache-without-revalidation 更合適,no-store才是真正地不進行快取 , 請讀者注意區別理解,
b.Connection欄位
Connection首部欄位具備如下兩個作用:1.控制不再轉發給代理的首部欄位;2.管理持久連接,

在客戶端發送請求和服務器回傳回應內,使用Connection首部欄位,可控制不再轉發給代理的首部欄位(即 Hop-by-hop Header 逐跳首部),
擴展:
HTTP首部欄位將定義成快取代理和非快取代理的行為 , 分成 2 種型別:
1.端到端首部 ( End - to - end Header )
分在此類別中的首部會轉發給請求 / 回應對應的最終接收目標,且必須保存在由快取生成的回應中,另外規定它必須被轉發,
2.逐跳首部 ( Hop - by - hop Header )
分在此類別中的首部只對單次轉發有效,會因通過快取或代理而不再轉發,HTTP /1.1 和之后版本中,如果要使用 hop-by-hop 首部,需提供 Connection 首部欄位,
HTTP /1.1中,除Connection、Keep-Alive、Proxy-Authenticate、Proxy-Authorization 、Trailer、TE、Transfer - Encoding、Upgrade 這 8 個首部欄位之外,其他所有欄位都屬于端到端首部,
HTTP /1.1 版本的默認連接都是持久連接,為此 , 客戶端會在持久連接上連續發送請求,當服務器端想明確斷開連接時 , 則指定 Connection 首部欄位的值為 Close:Connection:Close
HTTP /1.1 之前的 HTTP 版本的默認連接都是非持久連接,如果想在舊版本的 HTTP 協議上維持持續連接 , 則需要指定 Connection 首部欄位的值為Keep-Alive:Connection:Keep-Alive
c.Pragma欄位
Pragma是 HTTP /1.1 之前版本的歷史遺留欄位,僅作為與 HTTP /1.0 的向后兼容而定義,規范定義的形式唯一 :Pragma:no-cache
該首部欄位屬于通用首部欄位 , 但只用在客戶端發送的請求中,客戶端會要求所有的中間服務器不回傳快取的資源,
所有的中間服務器如果都能以 HTTP /1.1 為基準 , 那直接采用Cache-Control:no-cache 指定快取的處理方式是最為理想的,但要整體掌握全部中間服務器使用的 HTTP 協議版本卻是不現實的,因此 , 發送的請求會同時含有下面兩個首部欄位:
Cache-Control:no-cache
Pragma:no-cache
d. max-age與s-maxage指令
當客戶端發送的請求中包含 max-age 指令時,如果判定快取資源的快取時間數值比指定時間的數值更小,那么客戶端就接收快取的資源,另外,當指定max-age 值為 0,那么快取服務器通常需要將請求轉發給源服務器,當服務器回傳的回應中包含 max-age 指令時,快取服務器將不對資源的有效性再作確認,而 max-age數值代表資源保存為快取的最長時間,
s-maxage 指令的功能和 max-age 指令的相同,它們的不同點是 s-maxage 指令只適用于供多位用戶使用的公共快取服務器性,也就是說,對于向同一用戶重復回傳回應的服務器來說,這個指令沒有任何作用,
當使用 s-maxage 指令后,則直接忽略對Expires物體首部欄位及 max-age 指令的處理,
2.請求首部欄位 ( Request Header Fields )
從客戶端向服務器端發送請求報文時使用的首部,補充了請求的附加內容、客戶端資訊、回應內容相關優先級等資訊,
a.Accept欄位
Accept首部欄位可通知服務器,用戶代理能夠處理的媒體型別及媒體型別的相對優先級,可使用type/subtype 這種形式,一次指定多種媒體型別,
| 文本檔案 | text/html、text/plain、text/css application/json、application/xml |
| 圖片檔案 | image/gif、image/png... |
| 視頻檔案 | video/mpeg、video/quicktime... |
| 應用程式使用的二進制檔案 | application/octet-stream、application/zip... |
若想要給顯示的媒體型別增加優先級,則使用 q = 來額外表示權重值,用分號 ( ; ) 進行分隔, 權重值 q 的范圍是 0 ~ 1 ( 可精確到小數點后 3 位 ),默認為1且1為最大值,當服務器提供多種內容時 , 將會首先回傳權重值最高的媒體型別,
Accept:text/plain;q=0.3,text/html 相當于Accept:text/plain;q=0.3,text/html;q=1,即text/html的權重大,當服務器端存在text/plain、text/html型別的文本檔案時,會優先回傳html的,
b.Host欄位
首部欄位 Host 會告知服務器 , 請求的資源所處的互聯網主機名和埠號,Host 首部欄位在 HTTP /1.1 規范內是唯——個必須被包含在請求內的首部欄位,若服務器未設定主機名,直接發送一個空值即可,即Host:
首部欄位 Host 和以單臺服務器分配多個域名的虛擬主機的作業機制有很密切的關聯 , 這是首部欄位Host必須存在的意義,
3.回應首部欄位( Response Header Fields )
從服務器端向客戶端回傳回應報文時使用的首部,補充了回應的附加內容,也會要求客戶端附加額外的內容資訊,
a.ETag欄位
首部欄位 ETag 能告知客戶端物體標識,它是一種可將資源以字串形式做唯一性標識的方式,服務器會為每份資源分配對應的 ETag 值,資源被快取時,就會被分配唯一性標識,另外,當資源更新時, ETag 值也需要更新,生成ETag值時,并沒有統一的演算法規則,而僅僅是由服務器來分配,
ETag中有強 ETag 值和弱 ETag 值之分:
- 強 ETag 值:不論物體發生多么細微的變化都會改變其值,ETag:"******"
- 弱 ETag 值:只用于提示資源是否相同,只有資源發生了根本改變 , 產生差異時才會改變 ETag值, 這時 , 會在欄位值最開始處附加 W/,ETag:W/"******"
請求首部欄位 If-Match就需要用到ETag,它會告知服務器匹配資源所用的物體標記 ( ETag ) 值,這時的服務器無法使用弱 ETag 值,服務器會比對 If - Match 的欄位值和資源的 ETag 值,僅當兩者一致時,才會執行請求,反之,則回傳狀態碼 412 Precondition Failed 的回應,
4.物體首部欄位( Entity Header Fields )
針對請求報文和回應報文的物體部分使用的首部,補充了資源內容更新時間等與物體有關的
資訊,
5.非HTTP/1.1首部欄位
a.Set-Cookie欄位
b.Cookie欄位
Cookie:Status=enable
Cookie欄位會告知服務器,當客戶端想獲得HTTP狀態管理支持時,就會在請求中包含從服務器接收到的Cookie,
三、報文主體和物體主體
1.報文 ( message )
報文是 HTTP 通信中的基本單位 , 由 8 位組位元組流 ( Octet sequence , 其中 octet 為 8 個位元 ) 組成 , 通過 HTTP 通信傳輸,
2.物體 ( entity )
物體作為請求或回應的有效載荷資料 ( 補充項 ) 被傳輸 , 其內容由物體首部和物體主體組成,
HTTP報文的主體用于傳輸請求或回應的物體主體,通常,報文主體等于物體主體,只有當傳輸中進行編碼操作(為了提升傳輸速率)時,物體主體的內容發生變化,才導致它和報文主體產生差異,
四、內容編碼(壓縮)
內容編碼指明應用在物體內容上的編碼格式,并保持物體資訊原樣壓縮,內容編碼后的物體由客戶端接收并負責解碼,常用的內容編碼有以下幾種:
- gzip ( GNU zip )
- compress ( UNIX 系統的標準壓縮 )
- deflate ( zlib )
- identity ( 不進行編碼)
五、分塊傳輸編碼(分割發送)
把物體主體分塊的功能稱為分塊傳輸編碼(Chuncked Transfer Coding), 在傳輸大容量資料時,通過把資料分割成多塊,能夠讓瀏覽器逐步顯示頁面,
分塊傳輸編碼會將物體主體分成多個部分 ( 塊 ),每一塊都會用十六進制來標記塊的大小,而物體主體的最后一塊會使用 " 0 ( CR + LF ) " 來標記,使用分塊傳輸編碼的物體主體會由接收的客戶端負責解碼,恢復到編碼前的物體主體 ,
HTTP /1.1中存在一種稱為傳輸編碼 ( TransferCoding ) 的機制,它可以在通信時按某種編碼方式傳輸,但只定義作用于分塊傳輸編碼中,
六、多部分物件集合(含有多型別物體)
多部分物件集合指發送的一份報文主體內可含有多型別物體,通常是在圖片或文本檔案等上傳時使用,多部分物件集合包含的物件如下:
1.multipart/form-data:在web表單檔案上傳時使用,
2.multipart/byteranges:在狀態碼206(范圍請求)回應報文包含了多個范圍的內容時使用,
Content-type:在 HTTP 報文中使用多部分物件集合時,需要在首部欄位里加上 Content-type,
Content-Type:multipart/form-data;boundary=WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Type:multipart/byteranges;boundary=WebKitFormBoundary7MA4YWxkTrZu0gW
boundary :使用 boundary 字串來劃分多部分物件集合指明的各類物體,在 boundary 字串指定的各個物體的起始行之前插入 " -- " 標記, 而在多部分物件集合對應的字串的最后插入 " -- " 標記作為結束,
七、范圍請求(中斷后繼續下載)
指定范圍發送的請求叫做范圍請求( Range Request ) ,范圍請求可以實作在下載中斷處恢復下載,
執行范圍請求時,會用到首部欄位 Range來指定資源的 byte 范圍,byte 范圍的指定形式如下:
5001 ~ 10000 位元組:Range : bytes = 5001-10000
從 5001 位元組之后全部的位元組:Range : bytes = 5001-
從一開始到 3000 位元組和 5000 ~ 7000 位元組的多重范圍:Range : bytes = -3000,5000-7000
針對范圍請求,回應會回傳狀態碼為 206 PartialContent的回應報文,對于多重范圍的范圍請求,回應會在首部欄位 Content - Type 標明multipart / byteranges 后回傳回應報文,如果服務器端無法回應范圍請求,則會回傳狀態碼200 OK 和完整的物體內容,
八、內容協商
當瀏覽器的默認語言為英語或中文,訪問相同 URI的 Web 頁面時,則會顯示對應的英語版或中文版的Web頁面,這樣的機制稱為內容協商( Content Negotiation ) ,
內容協商機制是指客戶端和服務器端就回應的資源內容進行交涉,然后提供給客戶端最為適合的資源,內容協商會以回應資源的語言、字符集、編碼方式等作為判斷的基準,包含在請求報文中的某些首部欄位(Accept、Accept - Charset、Accept - Encoding、Accept - Language、Content - Language)就是判斷的基準,
內容協商技術有以下 3 種型別:
- 服務器驅動協商 ( Server-driven Negotiation ):由服務器端進行內容協商 . 以請求的首部欄位為參考 , 在服務器端自動處理 . 但對用戶來說 , 以瀏覽器發送的資訊作為判定的依據 , 并不一定能篩選出最優內容 .
- 客戶端驅動協商 ( Agent-driven Negotiation ):由客戶端進行內容協商的方式,用戶從瀏覽器顯示的可選項串列中手動選擇,還可以利用JavaScript腳本在 Web 頁面上自動進行上述選擇,比如按 OS 的型別或瀏覽器型別,自行切換成 PC 版頁面或手機版頁面,
- 透明協商(Transparent Negotiation ):是服務器驅動和客戶端驅動的結合體,是由服務器端和客戶端各自進行內容協商的一種方法,
——《圖解HTTP》筆記
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/357274.html
標籤:其他
