Http Headers爲何物

目錄

一、HTTP 請求內容

二、HTTP Headers分類

1、Genaral headers

2、Request headers

3、Response Headers

4、Entity Headers

三、HTTP 具體應用

1、Cookie

2、緩存

四、HTTP 請求 method

五、HTTP 狀態碼

1、1XX

2、2XX

3、3XX

4、4XX

5、5XX

六、MIME類型

七、HTTP 使用的認證方式

1、BASIC 認證

2、DIGEST 認證

3、SSL 客戶端認證

4、FormBase 認證

八、跨域資源共享(CORS)

1、簡單請求(不會觸發CORS預檢請求)

2、非“簡單請求”(觸發CORS預檢請求)

3、附帶身份憑證的請求

4、CORS幾個response header解釋


一、HTTP 請求內容

由於最新的http2,並沒有被各大瀏覽器廣泛使用,所以本文是基於http/1.1所編寫的。
同時經過檢測我們也發現,chrome等瀏覽器也正是使用http/1.1版本的。

圖片描述
關於http/1.1協議的詳情,可查看官方文檔

我們打開chrome的network,點擊任何一條request請求,即可發現,每個http headers都包含以下部分:Genaral,Request Headers,Response Headers,Request Payload。

General(不屬於headers,只用於收集請求url和響應的status等信息)
clipboard.png

Request Headers(請求headers)
clipboard.png

Response Headers(響應headers)
clipboard.png

Request Payload(請求參數)
clipboard.png


二、HTTP Headers分類

在http heanders中,爲了方便,分爲以下幾類:Genaral headers(和上面說的General不同,這個只是爲了方便統計),Request Headers,Response Headers,Entity Headers(也是爲了方便統計)。

圖片描述

所以,一個完整的請求頭/響應頭,應該除了自身,還包括 General Headers和Entity Headers。
clipboard.png

1、Genaral headers: 同時適用於請求和響應消息,但與最終消息傳輸的數據無關的消息頭。
2、Request Headers: 包含更多有關要獲取的資源或客戶端本身信息的消息頭。
3、Response Headers:包含有關響應的補充信息,如其位置或服務器本身(名稱和版本等)的消息頭。
4、Entity Headers:包含有關實體主體的更多信息,比如主體長(Content-Length)度或其MIME類型。

1、Genaral headers

Cache-Control——控制緩存的行爲; 詳情
Connection——決定當前的事務完成後,是否會關閉網絡連接; 詳情
Date——創建報文的日期時間; 詳情
Keep-Alive——用來設置超時時長和最大請求數;詳情
Via——代理服務器的相關信息;詳情
Warning——錯誤通知;詳情
Trailer——允許發送方在分塊發送的消息後面添加額外的元信息; 詳情
Transfer-Encoding——指定報文主體的傳輸編碼方式;詳情
Upgrade——升級爲其他協議;

2、Request headers

Accept——客戶端可以處理的內容類型;詳情
Accept-Charset——客戶端可以處理的字符集類型;詳情
Accept-Encoding——客戶端能夠理解的內容編碼方式;詳情
Accept-Language——客戶端可以理解的自然語言;詳情
Authorization——Web 認證信息;詳情
Cookie——通過Set-Cookie設置的值;詳情
DNT——表明用戶對於網站追蹤的偏好;詳情
From——用戶的電子郵箱地址;詳情
Host——請求資源所在服務器;詳情
If-Match——比較實體標記(ETag);詳情
If-Modified-Since——比較資源的更新時間;詳情
If-None-Match——比較實體標記(與 If-Match 相反);詳情
If-Range——資源未更新時發送實體 Byte 的範圍請求;詳情
If-Unmodified-Since——比較資源的更新時間(與 If-Modified-Since 相反);詳情
Origin——表明了請求來自於哪個站點;詳情
Proxy-Authorization——代理服務器要求客戶端的認證信息;詳情
Range——實體的字節範圍請求;詳情
Referer——對請求中 URI 的原始獲取方;詳情
TE——指定用戶代理希望使用的傳輸編碼類型;詳情
Upgrade-Insecure-Requests——表示客戶端優先選擇加密及帶有身份驗證的響應;詳情
User-Agent——瀏覽器信息;詳情

3、Response Headers

Accept-Ranges——是否接受字節範圍請求;詳情
Age——消息對象在緩存代理中存貯的時長,以秒爲單位;詳情
Clear-Site-Data——表示清除當前請求網站有關的瀏覽器數據(cookie,存儲,緩存);詳情
Content-Security-Policy——允許站點管理者在指定的頁面控制用戶代理的資源;詳情
Content-Security-Policy-Report-Only—— 詳情
ETag——資源的匹配信息;鏈接描述
Location——令客戶端重定向至指定 URI;詳情
Proxy-Authenticate——代理服務器對客戶端的認證信息;詳情
Public-Key-Pins——包含該Web 服務器用來進行加密的 public key (公鑰)信息;詳情
Public-Key-Pins-Report-Only——設置在公鑰固定不匹配時,發送錯誤信息到report-uri;詳情
Referrer-Policy——用來監管哪些訪問來源信息——會在 Referer 中發送;詳情
Server——HTTP 服務器的安裝信息;詳情
Set-Cookie——服務器端向客戶端發送 cookie;詳情
Strict-Transport-Security——它告訴瀏覽器只能通過HTTPS訪問當前資源;詳情
Timing-Allow-Origin——用於指定特定站點,以允許其訪問Resource Timing API提供的相關信息;詳情
Tk——顯示了對相應請求的跟蹤情況;詳情
Vary——服務器緩存的管理信息;詳情
WWW-Authenticate——定義了使用何種驗證方式去獲取對資源的連接;詳情
X-XSS-Protection——當檢測到跨站腳本攻擊 (XSS)時,瀏覽器將停止加載頁面;詳情

4、Entity Headers

Allow——客戶端可以處理的內容類型,這種內容類型用MIME類型來表示;詳情
Content-Encoding——用於對特定媒體類型的數據進行壓縮;詳情
Content-Language——訪問者希望採用的語言或語言組合;詳情
Content-Length——發送給接收方的消息主體的大小;詳情
Content-Location——替代對應資源的 URI;詳情
Content-Range——實體主體的位置範圍;詳情
Content-Type——告訴客戶端實際返回的內容的內容類型;詳情
Expires——包含日期/時間, 即在此時候之後,響應過期;詳情
Last-Modified——資源的最後修改日期時間;詳情

三、HTTP 具體應用

1、Cookie

HTTP 協議是無狀態的,主要是爲了讓 HTTP 協議儘可能簡單,使得它能夠處理大量事務。HTTP/1.1 引入 Cookie 來保存狀態信息。

Cookie 是服務器發送到用戶瀏覽器並保存在本地的一小塊數據,它會在瀏覽器之後向同一服務器再次發起請求時自動被攜帶上,用於告知服務端兩個請求是否來自同一瀏覽器。由於之後每次請求都會需要攜帶 Cookie 數據,因此會帶來額外的性能開銷(尤其是在移動環境下)。

Cookie 曾一度用於客戶端數據的存儲,因爲當時並沒有其它合適的存儲辦法而作爲唯一的存儲手段,但現在隨着現代瀏覽器開始支持各種各樣的存儲方式,Cookie 漸漸被淘汰。新的瀏覽器 API 已經允許開發者直接將數據存儲到本地,如使用 Web storage API(本地存儲和會話存儲)或 IndexedDB。

a、創建過程

服務器發送的響應報文包含Set-Cookie首部字段,客戶端得到響應報文後把 Cookie 內容保存到瀏覽器中。

HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: PHPSESSID=kq8v6iujarsgflkeq7shmai9c7

客戶端之後對同一個服務器發送請求時,會從瀏覽器中取出 Cookie 信息並通過 Cookie 請求首部字段發送給服務器。

GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: PHPSESSID=kq8v6iujarsgflkeq7shmai9c7

b、分類

會話期 Cookie:瀏覽器關閉之後它會被自動刪除,也就是說它僅在會話期內有效。
持久性 Cookie:指定一個特定的過期時間(Expires)或有效期(max-age)之後就成爲了持久性的 Cookie。
安全 Cookie:指定HttpOnly,這樣cookie不能使用 JavaScript 經由 Document.cookie 屬性,來防範跨站腳本攻擊(XSS)。
HTTPS Cookie: 指定Secure,只有在請求使用SSL和HTTPS協議的時候纔會被髮送到服務器。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;HttpOnly
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;Secure

2、緩存

降低客戶端獲取資源的延遲:緩存通常位於內存中,讀取緩存的速度更快。並且緩存在地理位置上也有可能比源服務器來得近,例如瀏覽器緩存(但是隻能緩存get,不能緩存其他類型請求)。
cache FAQ MDN

流程圖:
clipboard.png

a、判斷cache-control或者expires是否有效

clipboard.png

max-age值爲緩存的毫秒數。

可以看到response-headers中設置了cache-control,並大於0,則下次直接從緩存(from disk cache)中獲取

b、Etag判斷

當發現Cache-Control設置的毫秒數過期了,則直接發送請求:
——如果響應中包含Etag(服務器生成的值),則瀏覽器再次向web服務器發送請求並帶上頭If-None-Match(Etag的值),web服務器收到請求後發現有頭If-None-Match 則與被請求資源的相應校驗串進行比對,決定返回200或304(瀏覽器會從緩存中獲取)。
——如果響應中不包含Etag,則進行Last-Modified判斷

c、Last-Modified判斷

當發現response header中含有Last-Modified,則再次向web服務器請求時帶上頭 If-Modified-Since,web服務器收到請求後發現有頭If-Modified-Since 則與被請求資源的最後修改時間進行比對,然後服務器決定返回200或者304(緩存)

瀏覽器強制告訴服務器不緩存資源:

//request headers
Cache-Control:max-age=0, no-cache

四、HTTP 請求 method

五、HTTP 狀態碼

clipboard.png

1、1XX

  • 100(continue) 表明到目前爲止都很正常,客戶端可以繼續發送請求或者忽略這個響應。

2、2XX

  • 200(OK) 表示從客戶端發來的請求在服務器端被正常處理了。
  • 204(No Content) 該狀態碼代表服務器接收的請求已成功處理,但在返回的響應報文中不含實體的主體部分。
  • 206(Partial Content) 該狀態碼錶示客戶端進行了範圍請求,而服務器成功執行了這部分的 GET 請求。響應報文中包含由 Content-Range 指定範圍的實體內容。

3、3XX

  • 301(Moved Permanently) 永久性重定向。該狀態碼錶示請求的資源已被分配了新的 URI,以後應使用資源現在所指的 URI。
  • 302(Found) 臨時性重定向。比如在沒有登錄情況下訪問網站"個人中心",會重定向到登錄頁,但是你登錄後,訪問個人中心時,它又不會重定向到其他地方了。
  • 303(See Other) 和 302 有着相同的功能,但是 303 明確要求客戶端應該採用 GET 方法獲取資源。
  • 304(Not Modified) 如果請求報文首部包含一些條件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,如果不滿足條件,則服務器會返回 304 狀態碼。

4、4XX

  • 400(Bad Request) 該狀態碼錶示請求報文中存在語法錯誤。當錯誤發生時,需修改請求的內容後再次發送請求。
  • 401 Unauthorized 該狀態碼錶示發送的請求需要有認證信息。返回含有 401 的響應必須包含一個適用於被請求資源的 WWW-Authenticate 首部用以詢問用戶信息。當瀏覽器初次接收到 401 響應,會彈出認證用的對話窗口。第二次接收到,則不彈出,直接表示認證失敗。
  • 403(Forbidden) 對請求資源的訪問被服務器拒絕了,一般是未獲得文件系統的訪問授權,問權限出現某些問題。
  • 404(Not Found) 瀏覽器地址錯誤。服務器找不到對應資源。

5、5XX

  • 500(Internal Server Error) 服務器在執行時報錯。
  • 503(Service Unavailable) 服務器暫時處於超負載或正在進行停機維護,無響應。一般需要重啓服務器即可。

六、MIME類型

瀏覽器通常使用MIME類型(而不是文件擴展名)來確定如何處理文檔;因此設置正確的MIME類型附加到headers是非常重要的。
clipboard.png
除了上面的基本的5中類型外,還有一種類型,即multipart類型。

multipart/form-data 在表單中通過post上傳
multipart/byteranges (不常用,不知道)

一般的,如果沒有顯示的在request headers的Allow上設置類型,瀏覽器的MIME 嗅探會推測出來對應的類型,如果發現找不到特定的子類型,則給出默認類型,比如對於text文件類型若沒有特定的subtype,就使用 text/plain。類似的,二進制文件沒有特定或已知的 subtype,即使用 application/octet-stream。

七、HTTP 使用的認證方式

1、BASIC 認證(基本認證)
2、DIGEST 認證(摘要認證)
3、SSL 客戶端認證
4、FormBase 認證(基於表單認證)

1、BASIC 認證

當在瀏覽器端輸入一個url時,會自動彈出一個框,要求輸入用戶名和密碼。此種方式爲basic認證。
下面是認證執行過程:
第一步:在瀏覽器地址欄中輸入 http://localhost:8080/auth
第二步: 服務器執行,發現需要認證,返回這個請求的響應。並在response headers中添加WWW-Authenticate,將http請求狀態設置爲401.
clipboard.png
瀏覽器檢測到WWW-Authenticate爲basic後,自動彈出框。
clipboard.png
第三步: 當用戶看到框後,輸入 用戶名和密碼,瀏覽器會將用戶名和密碼通過base64方式編碼,然後添加到 request headers的 Authorization 中發送給服務器,瀏覽器驗證通過,返回200狀態碼
clipboard.png
如果驗證不通過,則繼續返回狀態碼401,提示驗證失敗。
clipboard.png

缺點:
BASIC 認證雖然採用 Base64 編碼方式,但這不是加密處理。不需要任何附加信息即可對其解碼。換言之,由於明文解碼後就是用戶 ID和密碼,在 HTTP 等非加密通信的線路上進行 BASIC 認證的過程中,如果被人竊聽,被盜的可能性極高。

2、DIGEST 認證

爲了彌補Basic認證沒有加密所帶來的不安全性,出現了DIGEST 認證。
過程如下:
第一步:在瀏覽器地址欄中輸入 http://localhost:8080/auth
第二步: 服務器執行,發現需要認證,返回這個請求的響應。並在response headers中添加WWW-Authenticate(包含有隨機碼nonce),將http請求狀態設置爲401.

瀏覽器檢測到WWW-Authenticate爲 digest 後,自動彈出框。

第三步: 當用戶看到框後,輸入 用戶名和密碼,瀏覽器會將用戶名和上步返回的nouce,添加到 request headers的 Authorization 中,同時也將經過 MD5 運算後的密碼字符串,生成key爲response,一併添加到Authorization 中。至此請求的request headers的Authorization 包含有如下信息。

//request header
Authorization: Digest username="my name",realm="DIGEST",nounce="xxxxxxxxxxx",algorithm="MD5",response="xxxxxxxxxxxxx"

然後發送給服務器,瀏覽器驗證通過,返回200狀態碼。

如果驗證不通過,則繼續返回狀態碼401,提示驗證失敗。

缺點: 雖然 DIGEST 認證提供了高於 BASIC 認證的安全等級, DIGEST 認證提供防止密碼被竊聽的保護機制,但並不存在防止用戶僞裝的保護機制,仍達不到多數 Web 網站對高度安全等級的追求標準。

3、SSL 客戶端認證

對於 BASIC 認證和 DIGEST 認證來說,只要輸入的用戶名和密碼正確,即可認證是本人的行爲。但如果用戶名和密碼被盜,就很有可能被第三者冒充。

而利用 SSL客戶端認證則可以避免該情況的發生。在SSL認證時,必須使用https協議。

由於SSL中的各種加密和祕鑰算法過於複雜,有興趣的可以直接閱讀SSL相關書籍,本文忽略詳細過程。

4、FormBase 認證

基於表單認證的標準規範尚未有定論,一般會使用 Cookie 來管理。
認證過程:
第一步:當用戶在瀏覽器的登錄頁面,輸入用戶名和密碼,通過http請求發送給後端。
第二步:後端保存用戶的信息到session中,並返回sessionId, 通過http添加到response headers的Set-cookie中

//response headers
Set-cookie: PHPSESSID=kq8v6iujarsgflkeq7shmai9c7

然後瀏覽器成功登錄,並跳轉頁面。
第三步:當用戶訪問個人中心或者其他頁面時。http請求的request header中會自動攜帶cookie

//request headers
Cookie: PHPSESSID=kq8v6iujarsgflkeq7shmai9c7

這樣,服務端會認爲是你本人在操作。

但是如果攻擊者通過“跨站腳本攻擊(XSS)”,通過docuemnt.cookie來獲取cookie,則sessionID很容易被盜。
爲減輕XSS造成的損失,可以事先在 Set-cookie內加上 httponly 屬性,這樣就禁止了docuemnt.cookie操作。

Set-cookie: PHPSESSID=kq8v6iujarsgflkeq7shmai9c7, httponly

八、跨域資源共享(CORS)

是一種機制,它使用額外的 HTTP 頭來告訴瀏覽器 讓運行在一個 origin (domain) 上的Web應用被准許訪問來自不同源服務器上的指定的資源。當一個資源從與該資源本身所在的服務器不同的域、協議或端口請求一個資源時,資源會發起一個跨域 HTTP 請求。

1、簡單請求(不會觸發CORS預檢請求)

需要滿足下列所有條件:
第一條: 請求方式必須爲 GET | HEAD | POST
第二條: Content-Type 的值必須屬於下列之一:application/x-www-form-urlencoded | multipart/form-data | text/plain
第三條: 在請求中,不會發送自定義的頭部(如X-Modified)

例如: 在http://foo.exmaple上要訪問 http://bar.other上的資源。則

//request headers上添加
Origin: http://foo.example
//response headers返回
Access-Control-Allow-Origin: *

由於在 http://foo.example 上要訪問 http://bar.other,所以http://bar.other必須要告訴其...,能不能訪問我。*號表示該資源可以被任意外域訪問。

如果返回

Access-Control-Allow-Origin: http://foo.example

表示,http://bar.other的資源只能被http://foo.example訪問,其他網站不能訪問我。

2、非“簡單請求”(觸發CORS預檢請求)

滿足下列條件之一:
第一條: http請求方式爲下列:PUT | DELETE | CONNECT | OPTIONS | TRACE | PATCH
第二條: Content-Type 的值不屬於下列之一: application/x-www-form-urlencoded | multipart/form-data | text/plain
第三條: 在請求中,發送自定義的頭部(如X-Modified)

如果在 http://foo.exmaple 上要訪問 http://bar.other/resources/po... 上的資源。且 request headers 中 Content-Type爲application/xml,請求method爲post。
那麼此請求是個“非簡單請求”。首先瀏覽器會自動發送帶有options選項的預檢請求,然後發送實際請求

//預檢請求request headers
OPTIONS /resources/post-here/ HTTP/1.1(自動,不需要設置)
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
//預檢請求返回response headers
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400

Access-Control-Allow-Origin 表明服務器允許任何其他服務器訪問自己。
Access-Control-Allow-Methods 表明服務器允許客戶端使用 POST, GET, OPTIONS 方法發起請求。
Access-Control-Allow-Headers 表明服務器允許請求中攜帶字段 X-PINGOTHER, Content-Type。
Access-Control-Max-Age 表明在86400內,不會再發送預檢請求。

然後瀏覽器接着發送實際請求

POST /resources/post-here/ HTTP/1.1
Content-Type: application/xml; charset=UTF-8

實際請求返回

HTTP/1.1 200 OK
Access-Control-Allow-Origin: * 

3、附帶身份憑證的請求

一般而言,對於跨域 XMLHttpRequest 或 Fetch 請求,瀏覽器不會發送身份憑證信息。如果要發送憑證信息,需要設置 XMLHttpRequest 的某個特殊標誌位。

var xhr = new XMLHttpRequest();
var url = 'http://xxxxxxxxx';
    
xhr.open('GET', url, true);
xhr.withCredentials = true;  // 設置發送人請求時 攜帶 cookie憑證
xhr.send(); 

請求發送

GET /resources/access-control-with-credentials/ HTTP/1.1
Cookie: pageAccess=2

請求返回

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://foo.example  //在攜帶憑證的請求中,返回不得設置爲*, 必須設置爲具體域名
Access-Control-Allow-Credentials: true  //必須攜帶這個,否則響應內容不會返回給請求的發起者

4、CORS幾個response header解釋

4.1 Access-Control-Allow-Origin
它的值只有兩種,要麼*, 好麼具體的域名 <origin>

4.2 Access-Control-Expose-Headers
在跨域訪問時,XMLHttpRequest對象的getResponseHeader()方法只能拿到一些最基本的響應頭:
Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma

無法訪問其他的響應頭(甚至在控制檯network中看不到),如 set-cookie等,如果要訪問其他頭,則需要服務器設置,將能返回的響應頭放入白名單

Access-Control-Expose-Headers: set-cookie

這樣瀏覽器就能夠通過getResponseHeader訪問set-cookie響應頭了

4.3 Access-Control-Max-Age
指定了預檢請求的結果能夠被緩存多久,在此時間內,不會再發起預檢請求。

Access-Control-Max-Age: <seconds>

4.4 Access-Control-Allow-Credentials
指定了當瀏覽器的credentials設置爲true時,是否允許瀏覽器讀取response的內容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章