前端學HTTP之報文首部


前面的話

  首部和方法配合工作,共同決定了客戶端和服務器能做什么事情。在請求和響應報文中都可以用首部來提供信息,有些首部是某種報文專用的,有些首部則更通用一些。本文將詳細介紹HTTP報文中的首部

 

結構

  HTTP首部字段是構成HTTP報文的要素之一。在客戶端與服務器之間以HTTP協議進行通信的過程中,無論是請求還是響應都會使用首部字段,它能起到傳遞額外重要信息的作用。使用首部字段是為了給瀏覽器和服務器提供報文主體大小、所使用的語言、認證信息等內容

  HTTP首部字段是由首部字段名和字段值構成的,中間用冒號“:” 分隔

首部字段名: 字段值

  例如,在HTTP首部中以Content-Type這個字段來表示報文主體的對象類型

Content-Type: text/html

  就以上述示例來看,首部字段名為Content-Type,字符串text/html是字段值

  另外,字段值對應單個 HTTP 首部字段可以有多個值,如下所示

Keep-Alive: timeout=15, max=100

 

分類

  可以將首部分為五個主要的類型,包括通用首部、請求首部、響應首部、實體首部和擴展首部

【通用首部】

  通用首部可以在客戶端、服務器和其他應用程序之間提供一些非常有用的通用功能。比如,Date首部就是一個通用首部,每一端都可以用它來說明構建報文的時間和日期:

Date: Tue, 3 Oct 2016 02:16:00 GMT

【請求首部】

  請求首部是請求報文特有的。它們為服務器提供了一些額外信息,比如客戶端希望接收什么類型的數據。例如,下面的Accept首部就用來告知服務器客戶端會接受與其請求相符的任意媒體類型:

Accept: */*

【響應首部】

  響應報文有自己的首部集,以便為客戶端提供信息(比如,客戶端在與哪種類型的服務器進行交互)。例如,下列Server首部就用來告知客戶端它在與一個版本1.0的Tiki-Hut服務器進行交互:

Server: Tiki-Hut/1.0

【實體首部】

  實體首部指的是用於應對實體主體部分的首部。比如,可以用實體首部來說明實體主體部分的數據類型。例如,可以通過下列Content-Type首部告知應用程序,數據是以iso-latin-1字符集表示的HTML文檔:

Content-Type:text/html; charset=iso-latin-1

【擴展首部】

  擴展首部是非標准的首部,由應用程序開發者創建,但還未添加到已批准的HTTP規范中去。即使不知道這些擴展首部的含義,HTTP程序也要接受它們並對其進行轉發

 

通用首部

  有些首部提供了與報文相關的最基本的信息,它們被稱為通用首部。它們像和事佬兒一樣,不論報文是何類型,都為其提供一些有用信息

  例如,不管是構建請求報文還是響應報文,創建報文的日期和時間都是同一個意思,因此提供這類信息的首部對這兩種類型的報文來說也是通用的

  下表列出了通用的信息性首部

1、Connection

  Connection首部主要用於連接管理,用於擴展keep-alive連接的HTTP/1.0客戶端,keep-alive連接用於控制信息。在HTTP/1.1中,能識別出大部分較老的語義,但這個首部被賦予了新的功能

  Connection首部可以承載3種不同類型的標簽:a、HTTP首部字段名,列出了只與此連接有關的首部;b、任意標簽值,用於描述此連接的非標准選項;c、值close,說明操作完成之后需關閉這條持久連接

  a、首部字段名

  應用程序收到帶有Connection首部的HTTP/1.1報文后,應該對列表進行解析,並刪除報文中所有在Connection首部列表中出現過的首部。它主要用於有代理網絡環境,這樣服務器或其他代理就可以指定不應傳遞的逐跳首部

  b、任意標簽值

  任意標簽值用於描述該連接。比如,如果是一個信用卡訂單的連接

Connection: bill-my-credit-card

  c、close

  HTTP1.1版本的默認連接是持久連接。當服務器端想明確斷開連接時,則指定Connection首部字段的值是Close

Connection: close

  d、Keep-alive

  HTTP1.0版本的默認連接都是非持久連接。因此,如果想在舊版本的HTTP協議上維持持久連接,需要將connection指定為keep-alive

 

2、Date

  Date首部給出了報文創建的日期和時間。服務器響應中要包含這個首部,因為緩存在評估響應的新鮮度時,要用到這個服務器認定的報文創建時間和日期。對客戶端來說,這個首部是可選的,但包含這個首部會更好

  HTTP/1.1 協議使用在 RFC1123 中規定的日期時間的格式,如下所示

Date: Tue, 03 Jul 2016 04:40:59 GMT

  之前的 HTTP 協議版本中使用在 RFC850 中定義的格式,如下所示

Date: Tue, 03-Jul-16 04:40:59 GMT

  除此之外,還有一種格式。它與C標准庫內的asctime()函數的輸出格式一致

Date: Tue Jul 03 04:40:59 2016

3、MIME-Version

  MIME是HTTP的近親。盡管兩者存在根本區別,但有些HTTP服務器確實構造了一些在MIME規范下同樣有效的報文。在這種情況下,服務器可以提供MIME版本的首部

  盡管HTTP/1.0規范中提到過這個首部,但它從未寫入官方規范。很多比較老的服務器會發送帶有這個首部的報文,但這些報文通常都不是有效的MIME報文,這樣會讓人覺得這個首部令人迷惑且不可信

MIME-Version: 1.0

4、Trailer

  Trailer首部用於傳輸編碼中,用於說明拖掛(在報文主體后記錄)中提供了哪些首部

Trailer: Expires

5、Transfer-Encoding

  首部字段Transfer-Encoding規定了傳輸報文主體時采用的編碼方式

  HTTP/1.1的傳輸編碼方式僅對分塊傳輸編碼有效

Transfer-Encoding: chunked

6、Upgrade

  首部字段Upgrade用於檢測HTTP協議及其他協議是否可使用更高的版本進行通信,其參數值可以用來指定一個完全不同的通信協議

  上圖用例中,首部字段Upgrade指定的值為TLS/1.0。Connection的值被指定為Upgrade。Upgrade首部字段產生作用的Upgrade對象僅限於客戶端和鄰接服務器之間。因此,使用首部字段Upgrade時,還需要額外指定Connection:Upgrade  

  對於附有首部字段Upgrade的請求,服務器可用101 Switching Protocols 狀態碼作為響應返回

7、Via

  使用首部字段Via是為了追蹤客戶端與服務器之間的請求和響應報文的傳輸路徑

  報文經過代理或網關時,會先在首部字段Via中附加該服務器的信息,然后再進行轉發。這個做法和traceroute及電子郵件的Received首部的工作機制很類似

  首部字段Via不僅用於追蹤報文轉發,還可避免請求回環發生。所以必須在經過代理時附加該首部字段內容

  上圖用例中,在經過代理服務器A時,Via首部附加了“1.0 gw.hackr.jp(Squid/3.1)”這樣的字符串值。行頭的1.0是指接收請求的服務器上應用的 HTTP協議版本。接下來經過代理服務器B時也是如此,在Via首部附加服務器信息,也可增加1個新的Via首部寫入服務器信息

  Via首部是為了追蹤傳輸路徑,所以經常會和TRACE方法一起使用。比如,代理服務器接收到由TRACE方法發送過來的請求(其中Max-Forwards:0)時,代理服務器就不能再轉發該請求了。這種情況下,代理服務器會將自身的信息附加到Via首部后,返回該請求的響應

【通用緩存首部】

  HTTP/1.0引入了第一個允許HTTP應用程序緩存對象本地副本的首部,這樣就不需要總是直接從源端服務器獲取了。最新的HTTP版本有非常豐富的緩存參數集

  下表列出了基本的緩存首部

 

1、Cache-Control

  通過指定首部字段Cache-Control的指令,就能操作緩存的工作機制

  指令的參數是可選的,多個指令之間通過“,”分隔。首部字段Cache-Control的指令可用於請求及響應時

Cache-Control: private, max-age=0, no-cache

  Cache-Control可用的指令按請求和響應分類如下所示

  下表為緩存請求指令

指令                  參數          說明
no-cache               無             強制向源服務器再次驗證
no-store               無             不緩存請求或響應的任何內容
max-age=[秒]           必需           響應的最大Age值
max-stale(= [秒])      可省略          接收已過期的響應
min-fresh=[秒]         必需            期望在指定時間內的響應仍有效
no-transform           無             代理不可更改媒體類型
only-if-cached         無             從緩存獲取資源
cache-extension       -             新指令標記(token)

  下表為緩存響應指令

指令                   參數          說明
public                 無              可向任意方提供響應的緩存
private                可省略          僅向特定用戶返回響應
no-cache              省略            緩存前必須先確認其有效性
no-store               無             不緩存請求或響應的任何內容
no-transform           無             代理不可更改媒體類型
must-revalidate        無             可緩存但必須再向源服務器進行確認
proxy-revalidate       無             要求中間緩存服務器對緩存的響應有效性再進行確認
max-age=[秒]           必需            響應的最大Age值
s-maxage=[秒]          必需           公共緩存服務器響應的最大Age值
cache-extension        -             新指令標記(token)

(public)

Cache-Control: public

  當指定使用public指令時,則明確表明其他用戶也可利用緩存

(private)

Cache-Control: private

  當指定private指令后,響應只以特定的用戶作為對象,這與public指令的行為相反

  緩存服務器會對該特定用戶提供資源緩存的服務,對於其他用戶發送過來的請求,代理服務器則不會返回緩存

 (no-cache)

Cache-Control: no-cache

  使用no-cache指令的目的是為了防止從緩存中返回過期的資源

  客戶端發送的請求中如果包含no-cache指令,則表示客戶端將不會接收緩存過的響應。於是,“中間”的緩存服務器必須把客戶端請求轉發給源服務器

  如果服務器返回的響應中包含no-cache指令,那么緩存服務器不能對資源進行緩存。源服務器以后也將不再對緩存服務器請求中提出的資源有效性進行確認,且禁止其對響應資源進行緩存操作

 (no-cache=Location)

Cache-Control: no-cache=Location

  由服務器返回的響應中,若報文首部字段Cache-Control中對no-cache字段名具體指定參數值,那么客戶端在接收到這個被指定參數值的首部字段對應的響應報文后,就不能使用緩存。換言之,無參數值的首部字段可以使用緩存。只能在響應指令中指定該參數

(no-store)

Cache-Control: no-store

  當使用no-store指令時,暗示請求(和對應的響應)或響應中包含機密信息

  因此,該指令規定緩存不能在本地存儲請求或響應的任一部分

(s-maxage)

Cache-Control: s-maxage=604800(單位:秒)

  s-maxage指令的功能和max-age指令的相同,它們的不同點是s-maxage指令只適用於供多位用戶使用的公共緩存服務器。也就是說,對於向同一用戶重復返回響應的服務器來說,這個指令沒有任何作用

  另外,當使用s-maxage指令后,則直接忽略對Expires首部字段及max-age指令的處理

(max-age)

Cache-Control: max-age=604800(單位:秒)

  當客戶端發送的請求中包含max-age指令時,如果判定緩存資源的緩存時間數值比指定時間的數值更小,那么客戶端就接收緩存的資源。另外,當指定max-age值為0,那么緩存服務器通常需要將請求轉發給源服務器

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

  應用HTTP/1.1版本的緩存服務器遇到同時存在Expires首部字段的情況時,會優先處理max-age指令,而忽略掉Expires首部字段。而HTTP/1.0版本的緩存服務器的情況卻相反,max-age指令會被忽略掉

(min-fresh)

Cache-Control: min-fresh=60(單位:秒)

  min-fresh指令要求緩存服務器返回至少還未過指定時間的緩存資源

  比如,當指定min-fresh為60秒后,過了60秒的資源都無法作為響應返回了

(max-stale)

Cache-Control: max-stale=3600(單位:秒)

  使用max-stale可指示緩存資源,即使過期也照常接收

  如果指令未指定參數值,那么無論經過多久,客戶端都會接收響應;如果指令中指定了具體數值,那么即使過期,只要仍處於max-stale指定的時間內,仍舊會被客戶端接收

(only-if-cached)

Cache-Control: only-if-cached

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

(must-revalidate)

Cache-Control: must-revalidate

  使用must-revalidate指令,代理會向源服務器再次驗證即將返回的響應緩存目前是否仍然有效

  若代理無法連通源服務器再次獲取有效資源的話,緩存必須給客戶端一條504(Gateway Timeout)狀態碼。另外,使用must-revalidate指令會忽略請求的max-stale指令(即使已經在首部使用了max-stale,也不會再有效果)

(proxy-revalidate)

Cache-Control: proxy-revalidate

  proxy-revalidate指令要求所有的緩存服務器在接收到客戶端帶有該指令的請求返回響應之前,必須再次驗證緩存的有效性

(no-transform)

Cache-Control: no-transform

  使用no-transform指令規定無論是在請求還是響應中,緩存都不能改變實體主體的媒體類型

  這樣做可防止緩存或代理壓縮圖片等類似操作

 (community)

Cache-Control: private, community="UCI"

  通過cache-extension標記(token),可以擴展Cache-Control首部字段內的指令

  如上例,Cache-Control首部字段本身沒有community這個指令。借助extension tokens實現了該指令的添加。如果緩存服務器不能理解community這個新指令,就會直接忽略。因此,extension tokens僅對能理解它的緩存服務器來說是有意義的

2、Pragma

  Pragma是HTTP/1.1之前版本的歷史遺留字段,僅作為與HTTP/1.0的向后兼容而定義。規范定義的形式唯一,如下所示

Pragma: no-cache

  該首部字段屬於通用首部字段,但只用在客戶端發送的請求中。客戶端會要求所有的中間服務器不返回緩存的資源

  所有的中間服務器如果都能以HTTP/1.1為基准,那直接采用Cache-Control:nocache指定緩存的處理方式是最為理想的。但要整體掌握全部中間服務器使用的HTTP協議版本卻是不現實的。因此,發送的請求會同時含有下面兩個首部字段

Cache-Control: no-cache 
Pragma: no-cache

 

請求首部

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

  下表列出了請求的信息性首部

 

  [注意]盡管有些客戶端實現了UA-*首部,但我們認為UA-*首部是有副作用的。不應該將內容,尤其是HTML,局限於特定的客戶端配置

1、From

From: info@hackr.jp

  首部字段From用來告知服務器使用用戶代理的用戶的電子郵件地址。通常,其使用目的就是為了顯示搜索引擎等用戶代理的負責人的電子郵件聯系方式。使用代理時,應盡可能包含From首部字段(但可能會因代理不同,將電子郵件地址記錄在User-Agent首部字段內)

2、host

Host: www.hackr.jp

  虛擬主機運行在同一個 IP上,因此使用首部字段 Host 加以區分

  首部字段Host會告知服務器,請求的資源所處的互聯網主機名和端口號。Host首部字段在HTTP/1.1規范內是唯一一個必須被包含在請求內的首部字段

  首部字段Host和以單台服務器分配多個域名的虛擬主機的工作機制有很密切的關聯,這是首部字段 Host 必須存在的意義

  請求被發送至服務器時,請求中的主機名會用IP地址直接替換解決。但如果這時,相同的IP地址下部署運行着多個域名,那么服務器就會無法理解究竟是哪個域名對應的請求。因此,就需要使用首部字段Host來明確指出請求的主機名。若服務器未設定主機名,那直接發送一個空值即可

3、Referer

Referer: http://www.hackr.jp/index.htm

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

  客戶端一般都會發送Referer首部字段給服務器。但當直接在瀏覽器的地址欄輸入URI,或出於安全性的考慮時,也可以不發送該首部字段

  因為原始資源的URI中的查詢字符串可能含有ID和密碼等保密信息,要是寫進Referer轉發給其他服務器,則有可能導致保密信息的泄露

  另外,Referer的正確的拼寫應該是Referrer,但不知為何,大家一直沿用這個錯誤的拼寫

4、User-Agent

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101

  首部字段User-Agent用於傳達瀏覽器的種類,User-Agent會將創建請求的瀏覽器和用戶代理名稱等信息傳達給服務器。由網絡爬蟲發起請求時,有可能會在字段內添加爬蟲作者的電子郵件地址。此外,如果請求經過代理,那么中間也很可能被添加上代理服務器的名稱

【Accept首部】

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

  下表列出了各種Accept首部

1、Accept

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

  Accept首部字段可通知服務器,用戶代理能夠處理的媒體類型及媒體類型的相對優先級。可使用type/subtype這種形式,一次指定多種媒體類型

  下面試舉幾個媒體類型的例子

  文本文件

text/html, text/plain, text/css ...
application/xhtml+xml, application/xml ...

  圖片文件

image/jpeg, image/gif, image/png ...

  視頻文件

video/mpeg, video/quicktime ...

  應用程序使用的二進制文件

application/octet-stream, application/zip ...

  比如,如果瀏覽器不支持PNG圖片的顯示,那Accept就不指定image/png,而指定可處理的image/gif和image/jpeg等圖片類型

  若想要給顯示的媒體類型增加優先級,則使用q=來額外表示權重值,用分號(;)進行分隔。權重值q的范圍是0-1(可精確到小數點后3 位),且1為最大值。不指定權重q值時,默認權重為q=1.0

  當服務器提供多種內容時,將會首先返回權重值最高的媒體類型

2、Accept-Charset

Accept-Charset: iso-8859-5, unicode-1-1;q=0.8

  Accept-Charset首部字段可用來通知服務器用戶代理支持的字符集及字符集的相對優先順序。另外,可一次性指定多種字符集。與首部字段Accept相同的是可用權重q值來表示相對優先級。該首部字段應用於內容協商機制的服務器驅動協商

3、Accept-Encoding

Accept-Encoding: gzip, deflate

  Accept-Encoding首部字段用來告知服務器用戶代理支持的內容編碼及內容編碼的優先級順序。可一次性指定多種內容編碼

  下面試舉出幾個內容編碼的例子

  gzip:由文件壓縮程序gzip(GNU zip)生成的編碼格式(RFC1952),采用Lempel-Ziv算法(LZ77)及32位循環冗余校驗(Cyclic Redundancy Check,通稱CRC)

  compress:由UNIX文件壓縮程序compress生成的編碼格式,采用Lempel-Ziv-Welch算法(LZW)

  deflate:組合使用zlib格式(RFC1950)及由deflate壓縮算法(RFC1951)生成的編碼格式。

  identity:不執行壓縮或不會變化的默認編碼格式

  采用權重q值來表示相對優先級,這點與首部字段Accept相同。另外,也可使用星號(*)作為通配符,指定任意的編碼格式

4、Accept-Language

Accept-Language: zh-cn,zh;q=0.7,en-us,en;q=0.3

  首部字段Accept-Language用來告知服務器用戶代理能夠處理的自然語言集(指中 文或英文等),以及自然語言集的相對優先級。可一次指定多種自然語言集
  和Accept首部字段一樣,按權重值q來表示相對優先級。在上述圖例中,客戶端在服務器有中文版資源的情況下,會請求其返回中文版對應的響應,沒有中文版時,則請求返回英文版響應

5、TE

TE: gzip, deflate;q=0.5

  首部字段TE會告知服務器客戶端能夠處理響應的傳輸編碼方式及相對優先級。它和首部字段Accept-Encoding的功能很相像,但是用於傳輸編碼

  首部字段TE除指定傳輸編碼之外,還可以指定伴隨trailer字段的分塊傳輸編碼的方式。應用后者時,只需把trailers賦值給該字段值TE: trailers

【條件請求首部】

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

  下表列出了各種條件請求首部

1、Expect

Expect: 100-continue

  客戶端使用首部字段Expect來告知服務器,期望出現的某種特定行為。因服務器無法理解客戶端的期望作出回應而發生錯誤時,會返回狀態碼417 Expectation Failed

  客戶端可以利用該首部字段,寫明所期望的擴展。雖然HTTP/1.1規范只定義了100continue(狀態碼 100 Continue 之意)

  等待狀態碼100響應的客戶端在發生請求時,需要指定Expect:100-continue

2、If-Match

If-Match: "123456"

  形如If-xxx這種樣式的請求首部字段,都可稱為條件請求。服務器接收到附帶條件的請求后,只有判斷指定條件為真時,才會執行請求

  首部字段If-Match,屬附帶條件之一,它會告知服務器匹配資源所用的實體標記(ETag)值。這時的服務器無法使用弱ETag值

  服務器會比對If-Match的字段值和資源的ETag值,僅當兩者一致時,才會執行請求。反之,則返回狀態碼412 Precondition Failed的響應

  還可以使用星號(*)指定If-Match的字段值。針對這種情況,服務器將會忽略ETag的值,只要資源存在就處理請求

3、If-Modified-Since

If-Modified-Since: Thu, 15 Apr 2004 00:00:00 GMT

  首部字段If-Modified-Since,屬附帶條件之一,它會告知服務器若If-Modified-Since字段值早於資源的更新時間,則希望能處理該請求。而在指定If-Modified-Since字段值的日期時間之后,如果請求的資源都沒有過更新,則返回狀態碼304 Not Modified的響應

4、If-None-Match

If-None-Match: *

  首部字段If-None-Match屬於附帶條件之一。它和首部字段If-Match作用相反。用於指定If-None-Match字段值的實體標記(ETag)值與請求資源的ETag 不一致時,它就告知服務器處理該請求

  在GET或HEAD方法中使用首部字段If-None-Match可獲取最新的資源。因此,這與使用首部字段If-Modified-Since時有些類似

5、Range

Range: bytes=5001-10000

  對於只需獲取部分資源的范圍請求,包含首部字段Range即可告知服務器資源的指 范圍。上面的示例表示請求獲取從第5001字節至第10000字節的資源

  接收到附帶Range首部字段請求的服務器,會在處理請求之后返回狀態碼為 206 Partial Content 的響應。無法處理該范圍請求時,則會返回狀態碼 200 OK 的響應及全部資源

6、If-Range

If-Range: "123456"

  首部字段If-Range屬於附帶條件之一。它告知服務器若指定的If-Range字段值(ETag值或者時間)和請求資源的ETag值或時間相一致時,則作為范圍請求處理。反之,則返回全體資源

  下面我們思考一下不使用首部字段If-Range發送請求的情況。服務器端的資源如果更新,那客戶端持有資源中的一部分也會隨之無效,當然,范圍請求作為前提是無效的。這時,服務器會暫且以狀態碼412 Precondition Failed作為響應返回,其目的是催促客戶端再次發送請求。這樣一來,與使用首部字段If-Range比起來,就需要花費兩倍的功夫

7、If-Unmodified-Since

If-Unmodified-Since: Thu, 03 Jul 2012 00:00:00 GMT

  首部字段If-Unmodified-Since和首部字段If-Modified-Since的作用相反。它的作用的是告知服務器,指定的請求資源只有在字段值內指定的日期時間之后,未發生更新的情況下,才能處理請求。如果在指定日期時間后發生了更新,則以狀態碼412 Precondition Failed作為響應返回

【安全請求首部】

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

  下表列出了一些安全請求首部

1、Authorization

Authorization: Basic dWVub3NlbjpwYXNzd29yZA==

  首部字段Authorization是用來告知服務器,用戶代理的認證信息(證書值)。通常,想要通過服務器認證的用戶代理會在接收到返回的401狀態碼響應后,把首部字段Authorization加入請求中。共用緩存在接收到含有Authorization首部字段的請求時的操作處理會略有差異

2、Cookie

Cookie: status=enable

  首部字段Cookie會告知服務器,當客戶端想獲得HTTP狀態管理支持時,就會在請求中包含從服務器接收到的Cookie。接收到多個Cookie時,同樣可以以多個Cookie形式發送

3、Cookie2

Cookie2: $version="1"

  Cookie2首部是用於客戶端識別和跟蹤的擴展首部。Cookie2用於識別請求發起者能夠理解哪種類型的Cookie

【代理請求首部】

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

  下表列出了一些代理請求首部

1、Max-Forwards

Max-Forwards: 10

  通過TRACE方法或OPTIONS方法,發送包含首部字段Max-Forwards的請求時,該字段以十進制整數形式指定可經過的服務器最大數目。服務器在往下一個服務器轉發請求之前,Max-Forwards的值減1后重新賦值。當服務器接收到Max-Forwards值為0的請求時,則不再進行轉發,而是直接返回響應

  使用HTTP協議通信時,請求可能會經過代理等多台服務器。途中,如果代理服務器由於某些原因導致請求轉發失敗,客戶端也就等不到服務器返回的響應了。對此,我們無從可知

  可以靈活使用首部字段Max-Forwards,針對以上問題產生的原因展開調查。由於當Max-Forwards字段值為0時,服務器就會立即返回響應,由此我們至少可以對以那台服務器為終點的傳輸路徑的通信狀況有所把握

2、Proxy-Authorization

Proxy-Authorization: Basic dGlwOjkpNLAGfFY5

  接收到從代理服務器發來的認證質詢時,客戶端會發送包含首部字段ProxyAuthorization的請求,以告知服務器認證所需要的信息

  這個行為是與客戶端和服務器之間的HTTP訪問認證相類似的,不同之處在於,認證行為發生在客戶端與代理之間。客戶端與服務器之間的認證,使用首部字段Authorization可起到相同作用

3、Proxy-Connection

  Netscape的瀏覽器及代理實現者們提出了一個對盲中繼問題的變通做法,這種做法並不要求所有的Web應用程序支持高版本的HTTP。這種變通做法引入了一個名為Proxy-Connection的新首部,解決了在客戶端后面緊跟着一個盲中繼所帶來的問題——但並沒有解決所有其他情況下存在的問題。在顯式配置了代理的情況下,現代瀏覽器都實現了Proxy-Connection,很多代理都能夠理解它

Proxy-Connection:Keep-alive

響應首部

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

  下表列出了一些響應的信息性首部

  [注意]Public首部在RFC 2068中定義,但在RFC 2616中並沒有出現。此外,RFC 2616中也沒有定義Title首部

1、Age

Age: 600

  首部字段Age能告知客戶端,源服務器在多久前創建了響應。字段值的單位為秒。若創建該響應的服務器是緩存服務器,Age值是指緩存后的響應再次發起認證到認證完成的時間值。代理創建響應時必須加上首部字段Age

2、Retry-After

Retry-After: 120

  首部字段Retry-After告知客戶端應該在多久之后再次發送請求。主要配合狀態碼503 Service Unavailable響應,或3xx Redirect響應一起使用

  字段值可以指定為具體的日期時間(Wed, 04 Jul 2012 06:34:24 GMT 等格式),也可以是創建響應后的秒數

3、Server

Server: Apache/2.2.17 (Unix)
Server: Apache/2.2.6 (Unix) PHP/5.2.5

  首部字段Server告知客戶端當前服務器上安裝的HTTP服務器應用程序的信息。不單單會標出服務器上的軟件應用名稱,還有可能包括版本號和安裝時啟用的可選項

4、Warning

  HTTP/1.1的Warning首部是從HTTP/1.0的響應首部(Retry-After)演變過來的。該首部通常會告知用戶一些與緩存相關的問題的警告

Warning: 113 gw.hackr.jp:8080 "Heuristic expiration" Tue, 03 Jul 2012 05

  Warning首部的格式如下,最后的日期時間部分可省略

Warning: [警告碼][警告的主機:端口號]“[警告內容]”([日期時間])

  HTTP/1.1中定義了7種警告。警告碼對應的警告內容僅推薦參考。另外,警告碼具備擴展性,今后有可能追加新的警告碼

  101 響應過時了

  當知道一條響應報文已過期時(比如,原始服務器無法進行再驗證時),就必須包含這條警告信息

  111 再驗證失敗

  如果緩存試圖與原始服務器進行響應再驗證,但由於緩存無法抵達原始服務器造成了再驗證失敗,那就必須在發給客戶端的響應中包含這條警告信息

  112 斷開連接操作

  通知性警告信息。如果緩存到網絡的連接被刪除了就應該使用此警告信息

  113 試探性過期

  如果新鮮性試探過期時間大於24小時,而且返回的響應使用期大於24小時,緩存中就必須包含這條警告信息

  199 雜項警告

  收到這條警告的系統不能使用任何自動響應。報文中可能,而且很可能應該包含一個主體,其中攜帶了為用戶提供的額外信息

  214 使用了轉換

  如果中間應用程序執行了任何會改變響應內容編碼的轉換,就必須由任意一個中間應用程序(比如代理)來添加這條警告

  299 持久雜項警告

  接收這條警告的系統不能進行任何自動的回應。錯誤中可能包含一個主體部分,它為用戶提供了更多的信息

【協商首部】

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

  下面列出了幾個首部,服務器可以用它們來傳遞與可協商資源有關的信息

1、Accept-Ranges

Accept-Ranges: bytes

  首部字段Accept-Ranges是用來告知客戶端服務器是否能處理范圍請求,以指定獲取服務器端某個部分的資源

  可指定的字段值有兩種,可處理范圍請求時指定其為bytes,反之則指定其為none

2、Vary

Vary: Accept-Language

  首部字段Vary可對緩存進行控制。源服務器會向代理服務器傳達關於本地緩存使用方法的命令

  從代理服務器接收到源服務器返回包含Vary指定項的響應之后,若再要進行緩存,僅對請求中含有相同Vary指定首部字段的請求返回緩存。即使對相同資源發起請求,但由於Vary指定的首部字段不相同,因此必須要從源服務器重新獲取資源

【安全響應首部】

  上面已經介紹過安全請求首部,本質上這里說的就是HTTP的質詢/響應認證機制的響應側。

  下表列出了安全響應首部

1、Proxy-Authenticate

Proxy-Authenticate: Basic realm="Usagidesign Auth"

  首部字段Proxy-Authenticate會把由代理服務器所要求的認證信息發送給客戶端。它與客戶端和服務器之間的HTTP訪問認證的行為相似,不同之處在於其認證行為是在客戶端與代理之間進行的。而客戶端與服務器之間進行認證時,首部字段WWW-Authorization有着相同的作用

2、Set-Cookie

Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31 GMT; path=/;

  當服務器准備開始管理客戶端的狀態時,會事先告知各種信息

  下面的表格列舉了Set-Cookie的字段值

屬性           說明
NAME=VALUE        賦予Cookie的名稱和其值(必需項)
expires=DATE        Cookie的有效期(若不明確指定則默認為瀏覽器 關閉前為止)
path=PATH         將服務器上的文件目錄作為Cookie的適用對象(若不指定則默認為文檔所在的文件目錄)
domain=域名       作為Cookie適用對象的域名(若不指定則默認為 創建Cookie的服務器的域名)
Secure          僅在HTTPS安全通信時才會發送Cookie
HttpOnly        加以限制,使Cookie不能被JavaScript腳本訪問

(expires)

  Cookie的expires屬性指定瀏覽器可發送Cookie的有效期。當省略expires屬性時,其有效期僅限於維持瀏覽器會話(Session)時間段內。這通常限於瀏覽器應用程序被關閉之前

  另外,一旦Cookie從服務器端發送至客戶端,服務器端就不存在可以顯式刪除Cookie的方法。但可通過覆蓋已過期的Cookie,實現對客戶端Cookie的實質性刪除操作

(path)

  Cookie的path屬性可用於限制指定Cookie的發送范圍的文件目錄。不過另有辦法可避開這項限制,看來對其作為安全機制的效果不能抱有期待

(domain)

  通過Cookie的domain屬性指定的域名可做到與結尾匹配一致。比如,當指定example.com后,除example.com以外,www.example.com或www2.example.com等都可以發送Cookie

  因此,除了針對具體指定的多個域名發送Cookie之外,不指定domain屬性顯得更安全

(secure)

  Cookie的secure屬性用於限制Web頁面僅在HTTPS安全連接時,才可以發送Cookie。發送Cookie時,指定secure屬性的方法如下所示

Set-Cookie: name=value; secure

  以上例子僅當在https://www.example.com/(HTTPS)安全連接的情況下才會進行Cookie的回收。也就是說,即使域名相同,http://www.example.com/(HTTP)也不會發生Cookie回收行為

  當省略secure屬性時,不論HTTP還是HTTPS,都會對Cookie進行回收

(HttpOnly)

  Cookie的HttpOnly屬性是Cookie的擴展功能,它使JavaScript腳本無法獲得Cookie。其主要目的為防止跨站腳本攻擊(Cross-site scripting,XSS)對Cookie的信息竊取

  發送指定HttpOnly屬性的Cookie的方法如下所示

Set-Cookie: name=value; HttpOnly

  通過上述設置,通常從Web頁面內還可以對Cookie進行讀取操作。但使用JavaScript的document.cookie就無法讀取附加HttpOnly屬性后的Cookie的內容了。因此,也就無法在XSS中利用JavaScript劫持Cookie了

  雖然是獨立的擴展功能,但IE6以上版本等瀏覽器都已經支持該擴展了。另外順帶一提,該擴展並非是為了防止XSS而開發的

3、Set-Cookie2

  Set-Cookie2比網景公司標准的可用屬性要多。下表對這些屬性做了快速匯總

  Cookie2會帶回與傳送的每個cookie相關的附加信息,用來描述每個cookie途徑的過濾器。每個匹配的cookie都必須包含來自相應Set-Cookie2首部的所有Domain、Port或Path屬性

  比如,假設客戶端以前曾收到下列五個來自Web站點www.joes-hardware.com的Set-Cookie2響應

Set-Cookie2: ID="29046"; Domain=".joes-hardware.com"
Set-Cookie2: color=blue Set-Cookie2: support-pref="L2";Domain="customer-care.joes-hardware.com" Set-Cookie2: Coupon="hammer027"; Version="1"; Path="/tools" Set-Cookie2: Coupon="handvac103"; Version="l”; Path="/tools/cordless"

  如果客戶端對路徑/tools/cordless/specials.html又發起了一次請求,會同時發送這樣一個很長的Cookie首部

Cookie:    $Version="l";
          ID-"29046";$Domain=".joes-hardware.com";   color="blue";   Coupon="hammer027"; $Path="/tools";   Coupon="handvac103"; $Path="/tools/cordless"

  所有匹配cookie都是和它們的set-Cookie2過濾器一同傳輸的,而且保留關鍵字都是以美元符號($)開頭的

4、WWW-Authenticate

WWW-Authenticate: Basic realm="Usagidesign Auth"

  首部字段WWW-Authenticate用於HTTP訪問認證。它會告知客戶端適用於訪問請求URI所指定資源的認證方案(Basic或是Digest)和帶參數提示的質詢(challenge)。狀態碼401 Unauthorized響應中,肯定帶有首部字段WWW-Authenticate

  上述示例中,realm字段的字符串是為了辨別請求URI指定資源所受到的保護策略

 

實體首部

  有很多首部可以用來描述HTTP報文的負荷。由於請求和響應報文中都可能包含實體部分,所以在這兩種類型的報文中都可能出現這些首部

  實體首部提供了有關實體及其內容的大量信息,從有關對象類型的信息,到能夠對資源使用的各種有效的請求方法。總之,實體首部可以告知報文的接收者它在對什么進行處理

  下表列出了實體的信息性首部

1、Allow

Allow: GET, HEAD

  首部字段Allow用於通知客戶端能夠支持Request-URI指定資源的所有HTTP方法。當服務器接收到不支持的HTTP方法時,會以狀態碼405 Method Not Allowed作為響應返回。與此同時,還會把所有能支持的HTTP方法寫入首部字段Allow后返回

2、Location

Location: http://www.usagidesign.jp/sample.html

  使用首部字段Location可以將響應接收方引導至某個與請求URI位置不同的資源。基本上,該字段會配合3xx:Redirection的響應,提供重定向的URI

  幾乎所有的瀏覽器在接收到包含首部字段Location的響應后,都會強制性地嘗試對已提示的重定向資源的訪問

【內容首部】

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

  下表列出了各種內容首部

  [注意]RFC 2616中沒有定義Content-Base首部

1、Content-Encoding

Content-Encoding: gzip

  首部字段Content-Encoding會告知客戶端服務器對實體的主體部分選用的內容編碼方式。內容編碼是指在不丟失實體信息的前提下所進行的壓縮

  主要采用以下4種內容編碼的方式:gzip、compress、deflate、identity

2、Content-Language

Content-Language: zh-CN

  首部字段Content-Language會告知客戶端,實體主體使用的自然語言(指中文或英文等語言)

3、Content-Length

Content-Length: 15000

  首部字段Content-Length表明了實體主體部分的大小(單位是字節)。對實體主體進行內容編碼傳輸時,不能再使用Content-Length首部字段

4、Content-Location

Content-Location: http://www.hackr.jp/index-ja.html

  首部字段Content-Location給出與報文主體部分相對應的URI。和首部字段 Location不同,Content-Location表示的是報文主體返回資源對應的URI

  比如,對於使用首部字段Accept-Language的服務器驅動型請求,當返回的頁面內容與實際請求的對象不同時,首部字段Content-Location內會寫明URI。(訪問http://www.hackr.jp/返回的對象卻是http://www.hackr.jp/index-ja.html等類似情況)

5、Content-MD5

Content-MD5: OGFkZDUwNGVhNGY3N2MxMDIwZmQ4NTBmY2IyTY==

  首部字段Content-MD5是一串由MD5算法生成的值,其目的在於檢查報文主體在傳輸過程中是否保持完整,以及確認傳輸到達

  對報文主體執行MD5算法獲得的128位二進制數,再通過Base64編碼后將結果寫入Content-MD5字段值。由於HTTP首部無法記錄二進制值,所以要通過Base64編碼處理。為確保報文的有效性,作為接收方的客戶端會對報文主體再執行一次相同的MD5算法。計算出的值與字段值作比較后,即可判斷出報文主體的准確性

  采用這種方法,對內容上的偶發性改變是無從查證的,也無法檢測出惡意篡改。其中一個原因在於,內容如果能夠被篡改,那么同時意味着Content-MD5也可重新計算然后被篡改。所以處在接收階段的客戶端是無法意識到報文主體以及首部字段Content-MD5是已經被篡改過的

6、Content-Range

Content-Range: bytes 5001-10000/10000

  針對范圍請求,返回響應時使用的首部字段Content-Range,能告知客戶端作為響應返回的實體的哪個部分符合范圍請求。字段值以字節為單位,表示當前發送部分及整個實體大小

7、Content-Type

Content-Type: text/html; charset=UTF-8

  首部字段Content-Type說明了實體主體內對象的媒體類型。和首部字段Accept一樣,字段值用type/subtype形式賦值

  參數charset使用iso-8859-1或euc-jp等字符集進行賦值

【實體緩存首部】

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

  下表列出了一些實體緩存首部

1、Etag

ETag: "82e22293907ce725faf67773957acd12"

  首部字段ETag能告知客戶端實體標識。它是一種可將資源以字符串形式做唯一性標識的方式。服務器會為每份資源分配對應的ETag值。另外,當資源更新時,ETag值也需要更新。生成ETag值時,並沒有統一的算法規則,而僅僅是由服務器來分配

  資源被緩存時,被分配唯一性標識。例如,當使用中文版瀏覽器訪問http://www.google.com/時,就會返回中文版對應的資源,而使用英文版瀏覽器訪問時,則會返回英文版對應的資源。兩者的URI是相同的,所以僅憑URI指定緩存的資源是相當困難的。若在下載過程中出現連接中斷、再連接的情況,都會依照ETag值來指定資源

  ETag中有強ETag值和弱ETag值之分

  強ETag值——不論實體發生多么細微的變化都會改變其值

ETag: "usagi-1234"

  弱ETag值只用於提示資源是否相同。只有資源發生了根本改變,產生差異時才會改變ETag值。這時,會在字段值最開始處附加W/

ETag: W/"usagi-1234"

2、Expires

Expires: Wed, 04 Jul 2012 08:26:05 GMT

  首部字段Expires會將資源失效的日期告知客戶端。緩存服務器在接收到含有首部字段Expires的響應后,會以緩存來應答請求,在Expires字段值指定的時間之前,響應的副本會一直被保存。當超過指定的時間后,緩存服務器在請求發送過來時,會轉向源服務器請求資源

  源服務器不希望緩存服務器對資源緩存時,最好在Expires字段內寫入與首部字段Date相同的時間值

  但是,當首部字段Cache-Control有指定max-age指令時,比起首部字段Expires,會優先處理max-age指令

3、Last-Modified

Last-Modified: Wed, 23 May 2012 09:59:55 GMT

  首部字段Last-Modified指明資源最終修改的時間。一般來說,這個值就是RequestURI指定資源被修改的時間。但類似使用CGI腳本進行動態數據處理時,該值有可能會變成數據最終修改時的時間

 

擴展首部

  HTTP首部字段是可以自行擴展的。所以在Web服務器和瀏覽器的應用上,會出現各種非標准的首部字段。接下來,我們就一些最為常用的首部字段進行說明

1、X-Frame-Options

X-Frame-Options: DENY

  首部字段X-Frame-Options屬於HTTP響應首部,用於控制網站內容在其他Web網站的Frame標簽內的顯示問題。其主要目的是為了防止點擊劫持(click jack ing)攻擊

  首部字段X-Frame-Options有以下兩個可指定的字段值

  DENY:拒絕

  SAMEORIGIN:僅同源域名下的頁面(Top-level-browsing-context)匹配時 許可。(比如,當指定http://hackr.jp/sample.html頁面為SAMEORIGIN時,那么hackr.jp上所有頁面的frame都被允許可加載該頁面,而example.com等其他域名的頁面就不行了)

  能在所有的Web服務器端預先設定好X-Frame-Options字段值是最理想的狀態

  對apache2.conf的配置實例

<IfModule mod_headers.c>
    Header append X-FRAME-OPTIONS "SAMEORIGIN" 
</IfModule>

2、X-XSS-Protection

X-XSS-Protection: 1

  首部字段X-XSS-Protection屬於HTTP響應首部,它是針對跨站腳本攻擊(XSS)的一種對策,用於控制瀏覽器XSS防護機制的開關

  首部字段X-XSS-Protection可指定的字段值如下

0:將 XSS 過濾設置成無效狀態
1:將 XSS 過濾設置成有效狀態

3、DNT

DNT: 1

  首部字段DNT屬於HTTP請求首部,其中DNT是 Do Not Track的簡稱,意為拒絕

  個人信息被收集,是表示拒絕被精准廣告追蹤的一種方法

  首部字段DNT可指定的字段值如下

0:同意被追蹤
1:拒絕被追蹤

  由於首部字段DNT的功能具備有效性,所以Web服務器需要對DNT做對應的支持

4、P3P

P3P: CP="CAO DSP LAW CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa OUR BUS IND UNI COM NAV INT"

  首部字段P3P屬於HTTP相應首部,通過利用P3P(The Platform for Privacy Preferences,在線隱私偏好平台)技術,可以讓Web網站上的個人隱私變成一種僅供程序可理解的形式,以達到保護用戶隱私的目的

  要進行P3P的設定,需按以下操作步驟進行

  步驟1:創建P3P隱私

  步驟2:創建P3P隱私對照文件后,保存命名在w3cp3p.xml

  步驟3:從P3P隱私中新建Compact policies后,輸出到HTTP響應中


免責聲明!

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



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