一、HTTP 概述
HTTP是基於客戶端/服務端(C/S)的架構模型,通過一個可靠的連結來交換資訊,是一個無狀態的請求/響應協議。
HTTP是一種能夠獲取如 HTML 這樣的網路資源的 protocol(通訊協議)。它是在 Web 上進行資料交換的基礎,是一種 client-server 協議,也就是說,請求通常是由像瀏覽器這樣的接受方發起的。
客戶端和服務端通過交換各自的訊息(與資料流正好相反)進行互動。由像瀏覽器這樣的客戶端發出的訊息叫做 requests,被服務端響應的訊息叫做 responses。
1. 基本性質
HTTP是無連線的:
無連線的含義是限制每次連線只處理一個請求。伺服器處理完客戶的請求,並收到客戶的應答後,即斷開連線。採用這種方式可以節省傳輸時間。 一個連線是由傳輸層來控制的,這從根本上不屬於HTTP的範圍。HTTP並不需要其底層的傳輸層協議是面向連線的,只需要它是可靠的,或不丟失訊息的(至少返回錯誤)。HTTP是可擴充套件的:
在 HTTP/1.0 中出現的 HTTP headers 讓協議擴充套件變得非常容易。只要服務端和客戶端就新 headers 達成語義一致,新功能就可以被輕鬆加入進來。HTTP是無狀態:
HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連線傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。 使用Cookies可以建立有狀態的會話。
2. HTTP 訊息結構
1. 請求報文
HTTP請求報文由:請求行、請求頭部、空行和請求資料四個部分組成。
複製程式碼
2. 響應報文
HTTP響應也由四個部分組成,分別是:狀態行、訊息報頭、空行和響應正文。
複製程式碼
二、HTTP請求方法
根據HTTP標準,HTTP請求可以使用多種請求方法。
HTTP1.0定義了三種請求方法:GET
, POST
, HEAD
方法。
HTTP1.1新增了五種請求方法:OPTIONS
, PUT
, DELETE
, TRACE
, CONNECT
方法。
方法 | 描述 |
---|---|
GET | 請求獲取Request-URI所標識的資源。 |
HEAD | 類似於get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭。 |
POST | 向指定資源提交資料進行處理請求(例如提交表單或者上傳檔案),資料被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。 |
PUT | 從客戶端向伺服器傳送的資料取代指定的文件的內容。 |
DELETE | 請求伺服器刪除 Request-URI 所標識的資源。 |
CONNECT | HTTP/1.1協議中預留給能夠將連線改為管道方式的代理伺服器,主要使用SSL和TLS將資料加密後通過網路隧道進行傳輸。 |
OPTIONS | 使伺服器傳回該資源所支援的所有HTTP請求方法。用 * 來代替資源名稱,向 Web 伺服器傳送 OPTIONS 請求,可以測試伺服器功能是否正常運作。 |
TRACE | 回顯伺服器收到的請求,主要用於測試或診斷。 |
其中,最常見的是 GET 和 POST 方法,如果是 RESful
介面的話一般會用到 PUT、DELETE、GET、POST(分別對應增刪查改)
三、HTTP 首部
主要分為通用首部、請求首部、響應首部和實體首部四種:
- 通用首部欄位:既可以出現在請求報文中,也可以出現在響應報文中,它提供了與報文相關的最基本的資訊;
- 請求首部欄位:從客戶端向伺服器傳送請求報文時使用的首部欄位,補充了請求的附加內容,客戶端資訊,響應內容相關優先順序等資訊;
- 響應首部欄位:從伺服器向客戶端返回響應報文時使用的首部欄位;補充了響應的附加內容,也會要求客戶端附加額外的內容資訊;
- 實體首部欄位:針對請求報文和響應報文的實體部分使用的首部,補充了資源內容的更新時間等與實體有關的資訊。
- 其他報文欄位:這些欄位不是HTTP協議中定義的,但被廣泛應用於HTTP請求中。
1. 通用首部欄位
首部欄位名 | 說明 |
---|---|
Cache-Control | 控制快取行為。 |
Connection | 管理持久連線,設定其值為Keep-Alive可實現長連線。 |
Date | 建立HTTP報文的日期和時間。 |
Pragma | Http/1.1之前的歷史遺留欄位,僅作為HTTP/1.0向後相容而定義,雖然是通用欄位,當通常被使用在客戶單的請求中,如Pragma: no-cache, 表示客戶端在請求過程中不循序服務端返回快取的資料。 |
Trailer | 報文尾部的首部。 |
Transfer-Encoding | 規定了傳輸報文主題時使用的傳輸編碼,如Transfer-Encoding: chunked。 |
Upgrade | 用於檢查HTTP協議或其他協議是否有可使用的更高版本。 |
Via | 追蹤客戶端和服務端之間的報文的傳輸路徑,還可避免會環的發生,所以在經過代理時必須新增此欄位。 |
Warning | Http/1.1的報文欄位,從Http/1.0的AfterRetry演變而來,用來告知使用者一些與快取相關的警告資訊。 |
2. 請求首部欄位
首部欄位名 | 說明 |
---|---|
Accept | 客戶端能夠處理的媒體型別 |
Accept-Charset | 表示客戶端支援的字符集。例如:Accept-Charset: GB2312, ISO-8859-1 |
Accept-Encoding | 表示客戶端支援的內容編碼格式。如:Accept-Encoding:gzip |
Accept-Language | 表示客戶端支援的語言。如:Accept-Language: zh-cn, en |
Authorization | 表示客戶端的認證資訊。客戶端在訪問需要認證的也是時,伺服器會返回401,隨後客戶端將認證資訊加在Authorization欄位中傳送到伺服器後,如果認證成功,則返回200 |
Host | 表示訪問資源所在的主機名,即URL中的域名部分。如:m.baidu.com |
If-Match | If-Match的值與所請求資源的ETag值(實體標記,與資源相關聯。資源變化,實體標記跟著變化)一致時,伺服器才處理此請求 |
If-Modified-Since | 用於確認客戶端擁有的本地資源的時效性 |
If-None-Match | If-Match的值與所請求資源的ETag值不一致時伺服器才處理此請求 |
If-Range | If-Range的值(ETag值或時間)與所訪問資源的ETag值或時間相一致時,伺服器處理此請求,並返回Range欄位中設定的指定範圍的資料。如果不一致,則返回所有內容。If-Range其實算是If-Match的升級版,因為它的值不匹配時,依然能夠返回資料,而If-Match不匹配時,請求不會被處理,需要資料時需再次進行請求 |
If-Unmodified-Since | 與If-Modified-Since相反,表示請求的資源在指定的時間之後未發生變化時,才處理請求,否則返回412 |
Max-Forwards | 表示請求可經過的伺服器的最大數目,請求每被轉發一次,Max-Forwards減1,當Max-Forwards為0時,所在的伺服器將不再轉發,而是直接做出應答。通過此欄位可定位通訊問題 |
Proxy-Authorization | 當客戶端接收到來自代理伺服器的認證質詢時,客戶端會將認證資訊新增到Proxy-Authorization來完成認證。與Authorization類似,只不過Authorization是發生在客戶端與服務端之間 |
Range | 獲取部分資源,例如:Range: bytes=500-1000表示獲取指定資源的第500到1000位元組之間的內容,如果伺服器能夠正確處理,則返回206作為應答,表示返回了部分資料,如果不能處理這種範圍請求,則以200作為應答,返回完整的資料 |
Referer | 告知伺服器請求是從哪個頁面發起的 |
User-Agent | 將發起請求的瀏覽器和代理名稱等資訊傳送給服務端 |
Cookie | 在請求時新增Cookie, 以實現HTTP的狀態記錄 |
3. 響應首部欄位
首部欄位名 | 說明 |
---|---|
Accept-Ranges | 是否接受位元組範圍。 |
Age | 服務端告知客戶端,源伺服器(而不是快取伺服器)在多久之前建立了響應,單位為秒。 |
ETag | 實體資源的標識,可用來請求指定的資源。 |
Location | 請求的資源所在的新位置。 |
Proxy-Authenticate | 將代理伺服器需要的認證資訊傳送給客戶端。 |
Retry-After | 服務端告知客戶端多久之後再重試,一般與503和3xx重定向型別的應答一起使用。 |
Server | 告知服務端當前使用的HTTP伺服器應用程式的相關資訊。 |
Vary | 代理伺服器快取的管理資訊。 |
WWW-Authenticate | 告知客戶端適用於所訪問資源的認證方案,如Basic或Digest。401的響應中肯定帶有WWW-Authenticate欄位。 |
Set-Cookie | 伺服器通過此欄位給客戶端傳遞Cookie資訊。 |
4. 實體首部欄位
首部欄位名 | 說明 |
---|---|
Allow | 通知客戶端,伺服器所支援的請求方法。 |
Content-Encoding | 告知客戶端,伺服器對資源的內容編碼。 |
Content-Language | 告知客戶端,資源所使用的自然語言。 |
Content-Length | 告知客戶端資源的長度 |
Content-Location | 告知客戶端資源所在的位置。 |
Content-Type | 告知客戶端資源的媒體型別,取值同請求首部欄位中的Accept。 |
Expires | 告知客戶端資源的失效日期。可用於對快取的處理。 |
Last-Modified | 告知客戶端資源最後一次修改的時間。 |
5. 其他報文欄位
X-Frame-Options:首部欄位X-Frame-Options屬於HTTP響應首部 用於控制網站內容在其他Web網站的Frame標籤內的顯示問題,主要目的是為了防止點選劫持攻擊
X-XSS-Protection:首部欄位X-XSS-Protection屬於HTTP響應首部 針對跨站指令碼攻擊的一種對策,用於控制瀏覽器XSS防護機制的開關
DNT(Do Not Track):拒絕個人資訊被收集,表示拒絕被精準廣告追蹤的一種方法
四、HTTP 狀態返回碼
狀態碼負責表示客戶端請求的返回結果、標記伺服器端是否正常、通知出現的錯誤。
狀態碼 | 類別 | 分類描述 |
---|---|---|
1XX | Informational(資訊性狀態碼) | 請求正在被處理 |
2XX | Success(成功狀態碼) | 請求處理成功 |
3XX | Redirection(重定向狀態碼) | 需要進行重定向 |
4XX | Client Error(客戶端錯誤狀態碼) | 伺服器無法處理請求 |
5XX | Server Error(伺服器錯誤狀態嗎) | 伺服器處理請求時出錯 |
1. 資訊響應
狀態碼 | 短句 | 含義 |
---|---|---|
100 | Continue | 繼續,客戶端應繼續其請求 |
101 | Switching Protocols | 切換協議,只能切換到更高階的協議 |
2. 成功響應
狀態碼 | 短句 | 含義 |
---|---|---|
200 | OK | 請求成功,一般用於GET與POST請求 |
201 | Created | 已建立,成功請求並建立了新的資源 |
202 | Accepted | 已接受,已經接受請求,但未處理完成 |
3. 重定向
狀態碼 | 短句 | 含義 |
---|---|---|
300 | Multiple Choices | 多種選擇,請求的資源可包括多個位置 |
301 | Moved Permanently | 永久移動 |
302 | Found | 臨時移動,GET 或者 HEAD 請求 |
303 | See Other | 檢視其它地址,與302類似。需使用GET請求檢視 |
304 | Not Modified | 未修改,伺服器返回此狀態碼時,不會返回任何資源 |
307 | Temporary Redirect | 臨時重定向,不該改變請求方法 |
4. 客戶端錯誤
狀態碼 | 短句 | 含義 |
---|---|---|
400 | Bad Request | 客戶端請求的語法錯誤,伺服器無法理解 |
401 | Unauthorized | 請求要求使用者的身份認證 |
402 | Payment Required | 保留,將來使用 |
403 | Forbidden | 伺服器理解請求客戶端的請求,但是拒絕執行此請求 |
404 | Not Found | 伺服器無法根據客戶端的請求找到資源(網頁) |
405 | Method Not Allowed | 客戶端請求中的方法被禁止 |
5. 伺服器錯誤
狀態碼 | 短句 | 含義 |
---|---|---|
500 | Internal Server Error | 伺服器內部錯誤,無法完成請求 |
501 | Not Implemented | 伺服器不支援請求的功能,無法完成請求 |
502 | Bad Gateway | 從遠端伺服器接收到了一個無效的響應 |
503 | Service Unavailable | 伺服器暫時的無法處理客戶端的請求 |
504 | Gateway Time-out | 未及時從遠端伺服器獲取請求 |
505 | HTTP Version not supported | 伺服器不支援請求的HTTP協議的版本,無法完成處理 |
五、HTTP 內容型別
Content-Type,內容型別,一般是指網頁中存在的Content-Type,用於定義網路檔案的型別和網頁的編碼,決定瀏覽器將以什麼形式、什麼編碼讀取這個檔案。
常見的媒體型別: 文字檔案:text/html, text/plain, text/css, application/xml 圖片檔案:iamge/jpeg, image/gif, image/png; 視訊檔案:video/mpeg 應用程式使用的二進位制檔案:application/octet-stream, application/zip
常用的內容編碼: gzip: 由檔案壓縮程式gzip生成的編碼格式; compress: 由Unix檔案壓縮程式compress生成的編碼格式; deflate: 組合使用zlib和deflate壓縮演算法生成的編碼格式; identity:預設的編碼格式,不執行壓縮。
六、HTTP Cookie
Cookie主要用於以下三個方面:
- 會話狀態管理(如使用者登入狀態、購物車、遊戲分數或其它需要記錄的資訊)
- 個性化設定(如使用者自定義設定、主題等)
- 瀏覽器行為跟蹤(如跟蹤分析使用者行為等)
Cookie曾一度用於客戶端資料的儲存,因當時並沒有其它合適的儲存辦法而作為唯一的儲存手段,但現在隨著現代瀏覽器開始支援各種各樣的儲存方式,Cookie漸漸被淘汰。由於伺服器指定Cookie後,瀏覽器的每次請求都會攜帶Cookie資料,會帶來額外的效能開銷(尤其是在移動環境下)。新的瀏覽器API已經允許開發者直接將資料儲存到本地,如使用 Web storage API (本地儲存和會話儲存)或 IndexedDB 。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
(1) 會話期Cookie 瀏覽器關閉之後它會被自動刪除,也就是說它僅在會話期內有效。
(2) 永續性Cookie 和關閉瀏覽器便失效的會話期Cookie不同,永續性Cookie可以指定一個特定的過期時間(Expires)或有效期(Max-Age)。
(3) Secure 和 HttpOnly
-
標記為
Secure
的Cookie只應通過被HTTPS協議加密過的請求傳送給服務端。 -
為避免跨域指令碼 (XSS) 攻擊,通過JavaScript的 Document.cookie API無法訪問帶有
HttpOnly
標記的Cookie,它們只應該傳送給服務端。
(4) Cookie的作用域 Domain 和 Path 標識定義了Cookie的作用域:即Cookie應該傳送給哪些URL。
七、HTTP/1.x的連線管理
連線管理是一個 HTTP 的關鍵話題:開啟和保持連線在很大程度上影響著網站和 Web 應用程式的效能。在 HTTP/1.x 裡有多種模型:短連線
, 長連線
, 和 HTTP 流水線
。
短連線 HTTP 最早期的模型,也是 HTTP/1.0 的預設模型,是短連線。每一個 HTTP 請求都由它自己獨立的連線完成;這意味著發起每一個 HTTP 請求之前都會有一次 TCP 握手,而且是連續不斷的。
長連線
一個長連線會保持一段時間,重複用於傳送一系列請求,節省了新建 TCP 連線握手的時間,還可以利用 TCP 的效能增強能力。當然這個連線也不會一直保留著:連線在空閒一段時間後會被關閉(伺服器可以使用 Keep-Alive
協議頭來指定一個最小的連線保持時間)。
HTTP 流水線 HTTP 流水線在現代瀏覽器中並不是預設被啟用的 HTTP/2 流水線已經被更好的演算法給代替,如 multiplexing
域名分片
除非你有緊急而迫切的需求,不要使用這一過時的技術,升級到 HTTP/2 就好了。在 HTTP/2 裡,做域名分片就沒必要了:HTTP/2 的連線可以很好的處理併發的無優先順序的請求。域名分片甚至會影響效能。大多數 HTTP/2 的實現還會使用一種稱作連線凝聚的技術去嘗試合併被分片的域名。
如果伺服器端想要更快速的響應網站或應用程式的應答,它可以迫使客戶端建立更多的連線。
瀏覽器有併發限制,是為了防止Dos/DDoS
攻擊。
例如,不要在同一個域名下獲取所有資源,假設有個域名是www.example.com
我們可以把它拆分成好幾個域名:www1.example.com、www2.example.com
所有這些域名都指向同一臺伺服器,瀏覽器會同時為每個域名建立多條連線。
這一技術被稱作域名分片(域名發散)
域名收斂
就是將靜態資源放在一個域名下,減少DNS解析的開銷。
八、 HTTP 快取
重用已獲取的資源能夠有效的提升網站與應用的效能。Web 快取能夠減少延遲與網路阻塞,進而減少顯示某個資源所用的時間。藉助 HTTP 快取,Web 站點變得更具有響應性。
1. 各種型別的快取
快取是一種儲存資源副本並在下次請求時直接使用該副本的技術。當 web 快取發現請求的資源已經被儲存,它會攔截請求,返回該資源的拷貝,而不會去源伺服器重新下載。
- 快取的種類有很多,其大致可歸為兩類:
私有與共享快取
。共享快取儲存的響應能夠被多個使用者使用,私有快取只能用於單獨使用者。
下文將主要介紹瀏覽器快取
,除此之外還有代理快取、閘道器快取、CDN、反向代理快取和負載均衡器等部署在伺服器上,為站點和 web 應用提供更好的穩定性、效能和擴充套件性。
常見的 HTTP 快取只能儲存 GET
響應,對於其他型別的響應則無能為力。
2. 快取規則
為了方便理解,我們認為瀏覽器存在一個快取資料庫,用於儲存快取資訊(實際上靜態資源是被快取到了記憶體和磁碟中),在瀏覽器第一次請求資料時,此時快取資料庫沒有對應的快取資料,則需要請求伺服器,伺服器會將快取規則和資料返回,瀏覽器將快取規則和資料儲存進快取資料庫。
我們可以將其分為兩大類強快取
、協商快取
2.1 強快取
瀏覽器如果判斷本地快取未過期,就直接使用,無需發起http請求(200 from memory/disk cache)
HTTP 1.0
伺服器使用的響應頭欄位為 Expires
,值為未來的絕對時間(時間戳),瀏覽器請求時的當前時間超過了 Expires 設定的時間,代表快取失效,需要再次向伺服器傳送請求,否則都會直接從快取資料庫中獲取資料。
HTTP 1.1
Cache-Control
是最重要的規則,預設為private。
private 私有快取 public 共享快取 max-age 快取的內容將在 xxx 秒後失效 no-cache 需要使用對比快取來驗證快取資料 no-store 所有內容都不會快取,強快取、協商快取都不會觸發
注意:在 HTTP 1.0 版本中,Expires
欄位的絕對時間是從伺服器獲取的,由於請求需要時間,所以瀏覽器的請求時間與伺服器接收到請求所獲取的時間是存在誤差的,這也導致了快取命中的誤差,在 HTTP 1.1 版本中,因為 Cache-Control
的值 max-age=xxx
中的 xxx 是以秒為單位的相對時間,所以在瀏覽器接收到資源後開始倒數計時,規避了 HTTP 1.0 中快取命中存在誤差的缺點,為了相容低版本 HTTP 協議,正常開發中兩種響應頭會同時使用,HTTP 1.1 版本的實現優先順序高於 HTTP 1.0
。
2.2 協商快取
瀏覽器第一次請求資料時,伺服器會將快取標識與資料一起返回給客戶端,客戶端將二者備份至快取資料庫中。再次請求資料時,客戶端將備份的快取標識傳送給伺服器,伺服器根據快取標識進行判斷,判斷成功後,返回304
狀態碼,通知客戶端比較成功,可以使用快取資料。
HTTP 1.0
- If-Modified-Since/Last-Modified
這兩個是成對出現的,屬於協商快取的內容,其中瀏覽器的頭部是
If-Modified-Since
,而服務端的是Last-Modified
,它的作用是,在發起請求時,如果If-Modified-Since和Last-Modified匹配,那麼代表伺服器資源並未改變,因此服務端不會返回資源實體,而是隻返回頭部,通知瀏覽器可以使用本地快取。Last-Modified,顧名思義,指的是檔案最後的修改時間,而且只能精確到1s以內
。
HTTP 1.1
- If-None-Match/E-tag
這兩個是成對出現的,屬於協商快取的內容,其中瀏覽器的頭部是
If-None-Match
,而服務端的是E-tag
,同樣,發出請求後,如果If-None-Match和E-tag匹配,則代表內容未變,通知瀏覽器使用本地快取,和Last-Modified不同,E-tag更精確,它是類似於指紋一樣的東西,基於FileEtag INode Mtime Size
生成,只要檔案變,指紋就會變,而且沒有1s精確度的限制
。
為了使快取策略更加健壯、靈活,HTTP 1.0 版本 和 HTTP 1.1 版本的快取策略會同時使用,甚至強制快取和協商快取也會同時使用,對於強制快取,伺服器通知瀏覽器一個快取時間,在快取時間內,下次請求,直接使用快取,超出有效時間,執行協商快取策略,對於協商快取,將快取資訊中的 Etag 和 Last-Modified 通過請求頭 If-None-Match 和 If-Modified-Since 傳送給伺服器,由伺服器校驗同時設定新的強制快取,校驗通過並返回 304 狀態碼時,瀏覽器直接使用快取,如果協商快取也未命中,則伺服器重新設定協商快取的標識。
3. 帶Vary頭的響應
Vary HTTP 響應頭決定了對於後續的請求頭,如何判斷是請求一個新的資源還是使用快取的檔案。
當快取伺服器收到一個請求,只有當前的請求和原始(快取)的請求頭跟快取的響應頭裡的Vary都匹配,才能使用快取的響應。
使用vary頭有利於內容服務的動態多樣性。例如,使用Vary: User-Agent頭,快取伺服器需要通過UA判斷是否使用快取的頁面。如果需要區分移動端和桌面端的展示內容,利用這種方式就能避免在不同的終端展示錯誤的佈局。另外,它可以幫助 Google 或者其他搜尋引擎更好地發現頁面的移動版本,並且告訴搜尋引擎沒有引入Cloaking。
更多文章在我的個人部落格www.williamife.com等你喲~
Thanks.