HTTP 的進化 - 理解真實的 HTTP 是如何工作的
原文: https://medium.com/platform-engineer/evolution-of-http-69cfe6531ba0
自從在 1989-1991 年間被 CERN(譯註:即“歐洲核子研究組織”的原稱 - Conseil Européen pour la Recherche Nucléaire)的 Tim Berners-Lee 發明出來以後,HTTP(超文字傳輸協議) 就一直是全球資訊網的基礎傳輸協議。在 C/S 計算模型中,HTTP 起到了一個“請求/響應”協議的作用。HTTP 標準由 IETF(因特網工程任務組) 和 W3C(全球資訊網聯盟)負責開發,並以一系列註釋請求(RFCs - Requests for Comments)的形式被髮布。HTTP 有 4 個版本:HTTP/0.9、HTTP/1.0、HTTP/1.1 以及 HTTP/2.0。當前通常使用 HTTP/1.1 版本,未來會是 HTTP/2.0。
HTTP/0.9 — 單行協議
- HTTP 的首個版本 — 一個簡單的 客戶端/伺服器、請求/響應、對 telenet 友好的協議
- 請求: 單行 (method + 所請求文件的 path)
- 支援的方法: 僅
GET
- 響應型別: 僅 超文字
- 響應後馬上結束的連線
- 沒有 HTTP headers (無法傳輸其他內容型別的檔案), 沒有 status/error 程式碼, 沒有 URLs, 沒有版本控制
$> telnet ashenlive.com 80
(連線1建立 - TCP 三次握手)
Connected to xxx.xxx.xxx.xxx
(請求)
GET /my-page.html
(超文字響應)
<HTML>
A very simple HTML page
</HTML>
(連線1關閉 - 斷掉 TCP)
複製程式碼
流行的 web 伺服器(Apache, Nginx)始終支援 HTTP/0.9。可以開啟一個 Telnet 會話訪問 google.com 試試。
HTTP/1.0 — 構建可擴充套件性
- 對瀏覽器友好的協議
- 提供了對請求和響應都包含豐富後設資料的 header 域 (HTTP 版本號、status code 和 content type)
- 響應:不再只限於超文字 (Content-Type 頭部提供了傳輸 HTML 之外檔案的能力 — 如指令碼、樣式或媒體檔案)
- 支援的方法:
GET
,HEAD
,POST
- 響應後馬上結束的連線
(連線1建立 - TCP 三次握手)
Connected to xxx.xxx.xxx.xxx
(請求)
GET /my-page.html HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)
(響應)
HTTP/1.0 200 OK
Content-Type: text/html
Content-Length: 137582
Expires: Thu, 01 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 1 May 1996 12:45:26 GMT
Server: Apache 0.84
<HTML>
A page with an image
<IMG SRC="/myimage.gif">
</HTML>
(連線1關閉 - 斷掉 TCP)
------------------------------------------
(連線2建立 - TCP 三次握手)
Connected to xxx.xxx.xxx.xxx
(請求)
GET /myimage.gif HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)
(響應)
HTTP/1.0 200 OK
Content-Type: text/gif
Content-Length: 137582
Expires: Thu, 01 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 1 May 1996 12:45:26 GMT
Server: Apache 0.84
[image content]
(連線2關閉 - 斷掉 TCP)
複製程式碼
HTTP/0.9 和 HTTP/1.0 的主要問題 — 為每個請求建立一個新連線
HTTP/0.9 和 HTTP/1.0 都需要為每次請求建立一個新的連線(並在收到對應的響應後立即關閉該連線)。每次新連線建立時,都要經歷一遍 TCP 三次握手。考慮到更好的效能,應該著重減少這些 C/S 之間的往返通訊。HTTP/1.1 用持久化連線解決了這個問題。
HTTP/1.1 — 標準化的協議
- 這是當前普遍使用的 HTTP 版本
- 進行了重大的效能優化和特性增強,分塊傳輸、壓縮/解壓、內容快取磋商、虛擬主機(有單個 IP 地址的主機具有多個域名)、更快的響應,以及通過增加快取節省了更多的頻寬
- 支援的方法:
GET
,HEAD
,POST
,PUT
,DELETE
,TRACE
,OPTIONS
- 長久的連線
(連線1建立 - TCP 三次握手)
Connected to xxx.xxx.xxx.xxx
(請求1)
GET /en-US/docs/Glossary/Simple_header HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header
(響應1)
HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Wed, 20 Jul 2016 10:55:30 GMT
Etag: "547fa7e369ef56031dd3bff2ace9fc0832eb251a"
Keep-Alive: timeout=5, max=1000
Last-Modified: Tue, 19 Jul 2016 00:59:33 GMT
Server: Apache
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding
[content]
(請求2)
GET /static/img/header-background.png HTTP/1.1
Host: developer.cdn.mozilla.net
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header
(響應2)
HTTP/1.1 200 OK
Age: 9578461
Cache-Control: public, max-age=315360000
Connection: keep-alive
Content-Length: 3077
Content-Type: image/png
Date: Thu, 31 Mar 2016 13:34:46 GMT
Last-Modified: Wed, 21 Oct 2015 18:27:50 GMT
Server: Apache
[image content of 3077 bytes]
(連線1關閉 - 斷掉 TCP)
複製程式碼
Keep-Alive 和 Upgrade 頭部
Keep-Alive 頭部
Connection: Keep-Alive
頭部在 HTTP/1.1 之前就存在,但在 HTTP/1.1 中該頭部被廢棄了,因為持久化連線變成了預設的行為(譯註:除非用Connection: Close
顯式關閉)。Keep-Alive
頭部可以被用於在主機之間定義持久連線通訊策略(比如使一個連線在某個事件發生之前都保持啟用)。這奠定了持久化、連線複用、管道化及其他很多現代 web 通訊協議中被加強能力的基礎。- 可以對客戶端、伺服器,或任何中間人分別設定獨立的
Keep-Alive
頭部。同時,主機可以增加timeout
引數以設定一個超時,或用max
引數限制每個連線的最大請求數。
HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Thu, 11 Aug 2016 15:23:13 GMT
Keep-Alive: timeout=5, max=1000
Last-Modified: Mon, 25 Jul 2016 04:32:39 GMT
Server: Apache
[body]
複製程式碼
- 受益於
Keep-Alive
頭部,HTTP 管道化實現了多個連線,以及其他更多改進。
Upgrade 頭部
- 藉助 HTTP/1.1 帶來的
Upgrade
頭部,便可用一個常用的協議起步,比如 HTTP/1.1,然後讓該連線切換到增強的協議型別,如 HTTP/2.0 或 WebSockets。 - 在一個升級過的連線中,不再有
max
引數了。升級後的協議為timeout
引數提供了新的策略(如果沒有特別定義,使用基礎協議預設的 timeout 值)。
HTTPS
- 加密超文字傳輸協議(HTTPS)是 HTTP 的安全版本,使用 SSL/TLS 完成安全加密通訊。
- 最初由網景公司在 90 年代中期開發,SSL(安全套接字層)是一種增強 HTTP 的密碼學協議,定義了客戶端和伺服器之間如何安全的互相通訊。TLS(安全傳輸層協議)是 SSL 的繼承者。
- 因為在客戶端和伺服器間提供了雙向加密,HTTPS 連線可以在資料傳輸中防止中間人攻擊和常見的安全威脅。
SSL/TLS 握手 — HTTPS 中的主要問題
- 儘管 HTTPS 設計上是安全的,但 SSL/TLS 握手過程在 HTTPS 連線之前消耗了顯著的時間;通常會耗費 1 至 2 秒,極大影響了網站啟動效能。
HTTP/2.0 和未來
所有以上提及的特性,當今都已經被主要的伺服器和瀏覽器所使用了。但像 HTTP/2.0、Server Side Events (SSE) 以及 WebSocket 這樣的現代增強功能,則改變了傳統 HTTP 的工作方式。
參考:
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP
- https://tools.ietf.org/id/draft-thomson-hybi-http-timeout-01.html
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism
- https://hpbn.co/brief-history-of-http/
長按二維碼或搜尋 fewelife 關注我們哦