1. 程式人生 > >HTTP首部解析

HTTP首部解析

至少 默認值 only 最小 identity 忽略 store 媒體類型 字段值

HTTP首部解析

轉載請註明出處:HTTP首部解析

文章目錄

1.與HTTP協議相關的Web服務器

2.HTTP首部


與HTTP協議相關的Web服務器

在說明HTTP首部相關知識之前,有必要先了解一下與HTTP協作的Web服務器。

用一臺主機實現多個域名

HTTP/1.1規範明確提出,允許一臺Web服務器實現多個域名。即使物理層面上只有一臺服務器,但只要使用虛擬主機(又稱虛擬服務器)的功能,就可以假想已經具有多臺服務器。

虛擬主機,又可以叫做虛擬服務器,是一種在單一主機獲主機群上,實現多網域服務的方法,可以運行多個網站或服務的技術。具體內容可參考wiki。傳送門:wiki: 虛擬主機

技術分享圖片

但是在同一臺服務器上部署多個網站域名會有一個問題,因為只有一臺物理服務器,意味著只有一個IP地址,在DNS服務將域名解析成IP地址之後,在收到請求之後就需要弄清楚究竟要訪問哪個域名。

這個問題其實有兩種方法可以解決。一是在發送請求時必須請求頭部字段中增加Host字段,表明請求的主機名。二是在一臺服務器上使用不同的IP地址來管理多個服務。

通信數據轉發程序:代理

代理服務器位於服務器和客戶端之間,接收由客戶端發送的請求並轉發給服務器,同時也接收服務器返回的響應並轉發給客戶端。前端工程師常用的抓包軟件Fiddler、Charles就是通過代理來實現抓包的。

代理服務器的基本行為就是接收客戶端發送的請求後轉發給服務器,代理不改變請求URI,會直接發送給前方具有資源的目標服務器。持有資源實體的服務器稱為源服務器,從源服務器返回的響應經過代理服務器後再傳給客戶端。每經過一次代理服務器,都會追加Via首部字段信息,表明經過的代理服務器信息。要不然都不知道誰跟誰了...

技術分享圖片

總的來說呢,使用代理服務器有以下好處

1.利用緩存技術減少服務器網絡帶寬流量的消耗

2.針對特定網站的訪問控制(控制哪些站點可以訪問服務器,哪些不能訪問,實現訪問過濾功能)

代理有多種使用方法,按照兩種基準分類,一種是是否緩存(緩存代理),另一種是是否會修改報文(透明代理)。詳細資料可參見wiki。傳送門:wiki: 代理服務器

保存資源的緩存

上面所說的緩存技術是指代理服務器或客戶端本地磁盤內保存的資源副本。利用緩存可以減少對源服務器的訪問(從代理服務器或瀏覽器讀取未過期的緩存資源),因此也就節省了通信流量和通信時間了。

技術分享圖片

緩存(代理)服務器的優勢在於利用緩存可避免多次從源服務器請求資源。因此客戶端可就近從瀏覽器或代理服務器上獲取資源,而源服務器也不必多次處理相同的請求了。

但是不管是瀏覽器或者是代理服務器上緩存的資源,都存在緩存過期的情況。如果緩存未過期,那麽就可以直接讀取緩存資源;如果緩存過期了,代理服務器將會再次從源服務器上獲取更新之後的資源。而瀏覽器並不會馬上發起一個請求給服務器,而是會發起一個條件GET請求(If-Modified-Since和Last-Modified字段)。

稍微總結一下。

1.一臺Web服務器可以配置多個域名,在請求時需要添加Host字段表示請求的主機名或者是多個IP管理不同的服務。

2.代理服務器的基本行為是將客戶端發送的請求轉發給服務器,然後直接將請求資源直接轉發給源服務器。可以利用代理服務器或者瀏覽器對響應進行緩存,減少同一請求對源服務器的訪問所產生的帶寬資源的浪費。

HTTP首部

請求頭和響應頭共有的首部字段包括:通用首部字段、實體首部字段、其他首部字段。而請求頭特有的首部字段是請求首部字段,響應頭特有的首部字段是響應首部字段。以下是HTTP/1.1定義了47種首部字段。

技術分享圖片
技術分享圖片
技術分享圖片
技術分享圖片

以下就簡單的說明一下每一個字段。

HTTP/1.1通用首部字段

通用首部字段是指,請求報文和響應報文雙方都會使用的首部。

Cache-Control指令:

能夠控制緩存的工作行為。指令的參數是可選的,多個指令之間通過‘,‘分隔。Cache-Control指令可用於請求和響應時。

技術分享圖片
技術分享圖片

public:緩存響應指令。明確表明其他用戶也可以利用緩存。

private:緩存響應指令。表示響應只以特定的用戶作為對象,代理服務器只會對特定用戶提供緩存資源,對於其他用戶發送過去來的請求,代理服務器則不會返回緩存。

no-cache:目的是為了防止從緩存中返回過期的資源。客戶端發送的請求如果包含no-cache指令,表示客戶端將不會接收緩存過的響應。於是,代理服務器必須把客戶端請求轉發給源服務器。如果服務器返回的響應中包含no-cache指令,那麽代理服務器不能對資源進行緩存。源服務器以後也將不再對代理服務器請求中提出的資源有效性進行確認,且禁止其對響應資源進行緩存操作。

no-store:禁止代理服務器緩存響應資源。

s-maxage:表示處於公共代理服務器情況下緩存過期沒有超過指定時間時,就會返回緩存。對於向同一個用戶重復返回響應的服務器來說,這個指令沒有任何作用。另外呢,當使用s-maxage指令後,則直接忽略對Expires首部字段及max-age指令的處理。例如Cache-Control: s-maxage=600(秒)表示公共代理服務器中緩存過期沒超過10分鐘則可以返回緩存資源。

max-age:形式為Cache-Control: max-age=600(秒)。如果客戶端發送的請求中包含max-age指令時,表示緩存過期沒超過指定的時間,那麽客戶端就接收緩存的資源。如果max-age值為0,表示代理服務器需要將請求轉發給源服務器。

當源服務器返回的響應中包含max-age指令時,代理服務器將不對資源的有效性進行確認,而max-age數值代表資源保存為緩存的最長時間。

在HTTP/1.1版本的代理服務器遇到同時存在Expires字段的情況下,會優先處理max-age指令而忽略掉Expires字段。

min-fresh:要求代理服務器返回至少還沒有超過指定時間的緩存資源。如Cache-Control: min-fresh=60(秒)當指定min-fresh為60秒後,60秒內的響應可以返回,而超過60秒的響應就無法返回了。

max-stale:表示緩存過期在指定時間內,客戶仍然會接收。如果未指定任何參數值,那麽無論經過多久,客戶端都會接受響應。

only-if-cached:表示客戶端僅在代理服務器本地緩存目標資源的情況下才會要求其返回。也就是說,該指令會要求代理服務器不重新加載響應,也不會再次確認資源的有效性。若發生請求代理服務器的本地緩存無響應,則返回狀態碼504 Gateway Timeout

must-revalidate:表示代理服務器會向源服務器再次驗證即將返回的響應緩存是否仍然有效。如果代理無法連通源服務器再次獲取有效資源的話,代理服務器會給客戶端返回504(Gateway Timeout)狀態碼。另外會忽略請求的max-stale指令。

proxy-revalidate:要求代理服務器對緩存的響應有效性再進行驗證。

no-transform:無論是在請求中還是在響應頭中,緩存都不能改變實體主體的媒體類型。

Connection

Connection字段具有以下兩個作用

控制不再轉發給代理服務器的首部字段:格式如下Connection: 不再轉發的首部字段名。在客戶端發送請求和服務器返回響應內,使用Connection字段可以控制不在轉發給代理服務器

技術分享圖片

持久連接:Connection: keep-alive。HTTP/1.1版本默認連接是持久連接。客戶端和服務器只需建立一次TCP連接,就可以相互進行多次HTTP通信了。直到有一方明確表示需要斷開TCP連接,持久連接才會結束。

Pragma

該首部字段僅作為與HTTP/1.0的向後兼容而定義。形式如下Pragma: no-cache。只用在響應頭中,表示代理服務器不能對響應進行緩存。

技術分享圖片

pargma首部字段與no-cache指令作用相同,但是為了兼容HTTP協議版本的問題,HTTP響應頭中會同時含有下面兩個字段。

技術分享圖片

Trailer

Trailer字段會事先說明在報文主體後記錄了哪些首部字段。主要用於HTTP/1.1版本的分塊傳輸編碼時。

技術分享圖片

Transfer-Encoding

Transfer-Encoding字段規定了傳輸報文主體時采用的編碼方式,僅對分塊傳輸編碼有效。

HTTP/1.1 200 OK Transfer-Encoding: chunked Connection: keep-alive cfo <--16進制(10進制為3312) ·····3312字節分塊數據····· 392 <--16進制(10進制為914) `````914字節分塊數據······

以上例子中,Transfer-Encoding字段值有效使用分塊傳輸編碼,且被分成了3312字節和914字節大小的分塊數據。

Upgrade

Upgrade字段檢測HTTP協議及其他協議是否可以使用更高的版本進行通信。如在使用WebSocket協議時會使用到此字段,在HTTP通信過程中,會使用HTTP升級將HTTP協議升級為WebSocket協議。之後服務器端返回101 Switching Protocols狀態碼表示協議轉換成功,此時就可以使用WebSocket協議進行全雙工雙向通信了。對WebSocket不熟悉的朋友可以參考這篇文章。傳送門:WebSocket協議解析

Via

Via字段的目的是為了追蹤客戶端與服務器之間的請求和響應報文的傳輸路徑。報文在經過代理服務器或網關時,會在Via字段中附加自身服務器的信息,然後再進行轉發。通常Via字段會與Max-Forwards字段配合使用。對Max-Forwards字段的解釋請看這篇文章。傳送門: Max-Forwards

技術分享圖片

請求首部字段

Accept

Accept字段可以通知服務器,用戶代理能夠處理的媒體類型及媒體類型的相對優先級。可以使用type/subtype這種形式,一次指定多種媒體類型,通過q=來給媒體類型增加優先級,最大為1.0, 最小為0,默認值為1.0

Accept:q=1.0 application/json; q=0.8 text/plain; q=0.7 */*

Accept-Charset

Accept-Charset字段用來通知服務器用戶代理支持的字符集及字符集的相對優先順序。另外,可一次性指定多種字符集。與Accept字段相同的是可用權重q值來表示相對優先級。

Accept-Encoding

Accept-Encoding字段用來通知服務器用戶代理支持的內容編碼及內容編碼的相對優先級。內容編碼包括gzip、compress、deflate、identity(不執行壓縮的默認編碼格式)等。

Accept-Language

Accept-Language用來告知服務器用戶代理能夠處理的自然語言集(中文或者英文), 以及自然語言集的相對優先級,可一次性指定多種自然語言集

Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

Authorization

Authorization字段用來告知服務器,用戶代理的認證信息(證書)。通常想要通過服務器認證的用戶代理會在接收到返回的401狀態碼響應後,把字段Authorization加入請求中。

Host

Host字段會告知服務器請求的資源所處的互聯網主機名和端口號。請求被發送到服務器時,會使用DNS服務將域名解析成IP地址。如果此時相同的IP地址下部署了多個域名(虛擬主機),那麽服務器就無法理解究竟是哪個域名對應的請求。因此就需要使用Host字段來明確指出請求的主機名。

技術分享圖片

If-None-Match
If-None-Match字段與Etag配合使用,當與Etag字段值不一致時,服務器會處理請求。如果一致,則服務器端會返回304 Not Modified。

在典型的用法中,當一個URL被請求,Web服務器會返回資源和其對應的Etag值,會被放置在HTTP響應頭中。

Etag: "686897696a7c876b7e"

然後,客戶端可以決定是否緩存這個資源和Etag。以後,如果客戶端想再次請求相同的url,將會發送一個包含已保存的Etag和If-None-Match字段的請求。

If-None-Match: "686897696a7c876b7e"

客戶端請求之後,服務器可能會比較客戶端的Etag和當前版本資源的ETag。如果ETag值匹配,這就意味著資源沒有改變,服務器便會發送回一個極短的響應,包含HTTP “304 Not Modified”的狀態。304狀態告訴客戶端,它的緩存版本是最新的,並應該使用它。
然而,如果ETag的值不匹配,這就意味著資源很可能發生了變化,那麽,一個完整的響應(200 OK)就會被返回,包括資源的內容,就好像ETag沒有被使用。這種情況下,客戶端可以用新返回的資源和新的ETag替代先前的緩存版本。

If-Modified-Since

If-Modified-Since字段與響應頭的Last-Modified字段匹配使用。當Last-Modified字段值的時間在其之後,表示資源發生了更新,則服務器會返回200 OK的狀態碼,當Last-Modified字段值的時間在其之前,表明資源沒有發生更新,則服務器會返回304 Not Modified狀態碼。當與If-None-Match字段聯合使用的時候,If-Modified-Since字段會被忽略,除非服務器不支持If-None-Match字段。If-Modified-Since用於確認代理服務器或客戶端擁有的本地資源的有效性。

技術分享圖片

If-Range

If-Range字段會告知服務器若指定的If-Range字段值和請求資源的Etag值獲時間相一致,則作為範圍請求處理,返回的響應頭會包含Content-Range字段,表示返回的範圍字節數。反之,則返回全體資源。此字段會與Range字段配合使用。

技術分享圖片

Proxy-Authorization

Proxy-Authorization: Basic dFDGADdjgjadfDSFJ5

接收到代理服務器發送過來的認證信息之後,客戶端會發送包含該首部字段的請求,以告知服務器認證所需要的信息。

Referer

Referer字段會告知服務器請求的原始資源的URI。

技術分享圖片

響應首部字段

Accept-Ranges

Accpet-Ranges字段用來告知客戶端服務器能否處理範圍請求,以指定獲取服務器端某個部分的資源。可指定的字段值有兩種,可處理範圍請求時指定其為bytes,反之指定為none。

技術分享圖片

ETag

服務器會為每份資源分配對應的ETag值,當資源更新時,ETag值也需要更新。ETag字段通常與If-None-Match字段配合使用。當ETag值與If-None-Match值相互匹配時,表示請求的資源沒有發生變化,則服務器會返回304 Not Modified狀態碼;如果相互不匹配,則會返回200 OK狀態碼。另外,ETag分為強ETag和弱ETag,它們通過ETag標識符的開頭是否存在“W/”來區分,如

"123456789"   -- 一個強ETag驗證符
W/"123456789"  -- 一個弱ETag驗證符

具體的區別可參考wiki。傳送門: HTTP ETag

Proxy-Authenticate && WWW-Authenticate
Proxy-Authenticate字段會把有代理服務器所要求的認證信息發送給客戶端,通常與Proxy-Authorization字段配合使用。

WWW-Authenticate字段用於HTTP訪問認證。通常與Authorization字段配合使用。

實體首部字段

實體首部字段是包含在請求報文和響應報文中的實體部分所使用的首部,用於補充內容的更新時間等與實體相關的信息。
Allow

形式如Allow: GET, POST。Allow字段用於通知客戶端能夠支持的HTTP方法。當服務器接收到不支持的HTTP方法時,會以狀態碼405 Method Not Allowed作為響應返回。

Content-Encoding

該字段會告知客戶端服務器對實體的主體部分選用的內容編碼方式。主要采用4種內容編碼方式:gzip、compress、deflate、identity。

Content-Language && Content-Length

Content-Language告知客戶端實體主體采用的自然語言集。Content-Length告知客戶端實體主體的大小。

Content-Range && Content-Type

Content-Range告知客戶端響應返回的實體的哪個部分符合範圍請求,該字段針對範圍請求。字段值以字節為單位,表示當前發送部分及整個實體大小。形式如Content-Range: bytes 5001-10000/10000

Content-Type告知客戶端實體主體采用的媒體類型,媒體類型與Accept字段相同。

Expries

Expries字段用於告知客戶端資源的過期時間。如果是代理服務器接收到帶有Expires字段的響應時,會將資源緩存起來。當請求相同資源且未超過指定時間時,會返回緩存的資源。當超過指定時間後,代理服務器會將請求轉發給源服務器。如果不希望代理服務器對資源進行緩存時,可以將Expires字段設置成與Date字段的值相同。在瀏覽器方面,當請求的資源過期時,不會立馬向源服務器發起請求,而是會先發起條件請求(If-Modified-Since與Last-Modifed字段)。

當Expires字段遇上Cache-Control字段的max-age指令時,會優先處理max-age指令。

為Cookie服務的字段

由於HTTP是無狀態協議,因此需要Cookie結合HTTP來實現用戶的狀態管理。對於Cookie的說明可以看這篇文章。傳送門:前端存儲方案


參考資料

1.《圖解HTTP》

2.MDN web docs

3.維基百科

HTTP首部解析