HTTP 的演變

HTTP (超文字傳輸協議) 是全球資訊網的基礎協議。由蒂姆·伯納斯-李和他的團隊在 1989 年至 1991 年間開發,HTTP 經歷了許多變化,這些變化在保持其簡單性的同時,也塑造了其靈活性。繼續閱讀,瞭解 HTTP 如何從一個旨在在半信任實驗室環境中交換檔案的協議,演變為一個承載高畫質影像和影片以及 3D 內容的現代網際網路迷宮。

全球資訊網的發明

1989 年,蒂姆·伯納斯-李在 CERN 工作期間,撰寫了一份關於在網際網路上構建超文本系統的提案。最初稱為 Mesh,在 1990 年實現時,它被重新命名為 World Wide Web。它建立在現有的 TCP 和 IP 協議之上,由 4 個構建模組組成:

  • 一種表示超文字文件的文字格式,即 超文字標記語言 (HTML)。
  • 一種用於交換這些文件的協議,即 超文字傳輸協議 (HTTP)。
  • 一個用於顯示(和編輯)這些文件的客戶端,第一個網路瀏覽器名為 WorldWideWeb
  • 一個用於訪問文件的伺服器,即 httpd 的早期版本。

這四個構建模組在 1990 年底完成,第一批伺服器在 1991 年初在 CERN 之外執行。1991 年 8 月 6 日,蒂姆·伯納斯-李在公共新聞組 alt.hypertext 發表了一篇帖子。這現在被認為是全球資訊網作為一個公共專案的正式開始。

早期階段使用的 HTTP 協議非常簡單。它後來被稱為 HTTP/0.9,有時也被稱為單行協議。

HTTP/0.9 – 單行協議

HTTP 的初始版本沒有版本號;它後來被稱為 0.9,以區別於後續版本。HTTP/0.9 極其簡單:請求只由一行組成,以唯一的可能方法 GET 開頭,後跟資源的路徑。完整的 URL 沒有包含在內,因為一旦連線到伺服器,協議、伺服器和埠就不再是必需的。

http
GET /my-page.html

響應也極其簡單:它只包含檔案本身。

html
<html>
  An text-only web page
</html>

與後續演變不同,沒有 HTTP 頭。這意味著只能傳輸 HTML 檔案。沒有狀態碼或錯誤碼。如果出現問題,會生成一個特定的 HTML 檔案,其中包含問題的描述供人類閱讀。

HTTP/1.0 – 構建可擴充套件性

HTTP/0.9 非常有限,但瀏覽器和伺服器很快使其更加通用。

  • 版本資訊隨每個請求傳送(HTTP/1.0 附加到 GET 行)。
  • 響應開始時還會發送一個狀態碼行。這允許瀏覽器自身識別請求的成功或失敗,並相應地調整其行為。例如,以特定方式更新或使用其本地快取。
  • HTTP 頭的概念被引入到請求和響應中。元資料可以傳輸,協議變得極其靈活和可擴充套件。
  • 由於 Content-Type 頭,除了純 HTML 檔案之外的文件也可以傳輸。

此時,典型的請求和響應如下所示:

http
GET /my-page.html HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

HTTP/1.0 200 OK
Date: Tue, 15 Nov 1994 08:12:31 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/html
<HTML>
A page with an image
  <IMG SRC="/my-image.gif">
</HTML>

緊接著是第二次連線和獲取影像的請求(以及相應的響應):

http
GET /my-image.gif HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

HTTP/1.0 200 OK
Date: Tue, 15 Nov 1994 08:12:32 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/gif
(image content)

在 1991 年至 1995 年間,這些是採用試探性方法引入的。伺服器和瀏覽器會新增一個功能,並檢視它是否受到歡迎。互操作性問題很常見。為了解決這些問題,1996 年 11 月釋出了一份描述常見做法的資訊性文件。這被稱為 RFC 1945,並定義了 HTTP/1.0。

HTTP/1.1 – 標準化協議

與此同時,適當的標準化正在進行中。這與 HTTP/1.0 的各種實現並行進行。HTTP 的第一個標準化版本 HTTP/1.1 於 1997 年初發布,僅比 HTTP/1.0 晚幾個月。

HTTP/1.1 澄清了歧義並引入了許多改進:

  • 連線可以重用,這節省了時間。它不再需要多次開啟以顯示單個原始文件中嵌入的資源。
  • 添加了管道化。這允許在第一個請求的響應完全傳輸之前傳送第二個請求。這降低了通訊延遲。
  • 也支援分塊響應。
  • 引入了額外的快取控制機制。
  • 引入了內容協商,包括語言、編碼和型別。客戶端和伺服器現在可以就交換哪些內容達成一致。
  • 由於 Host 頭,從同一 IP 地址託管不同域的能力允許伺服器託管。

以下示例說明了透過單個持久 TCP 連線傳送的 HTTP/1.1 請求的典型序列,演示了客戶端如何重用連線以更有效地載入資源。第一個請求檢索一個網頁,伺服器響應一個 HTML 文件。客戶端隨後會隨著在 HTML 中遇到 CSS 和 JavaScript 資源而順序傳送額外的請求。

http
GET /en-US/docs/ HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:141.0) Gecko/20100101 Firefox/141.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, zstd
Connection: keep-alive

HTTP/1.1 200 OK
accept-ranges: none
content-encoding: br
date: Tue, 01 Jul 2025 08:32:50 GMT
expires: Tue, 01 Jul 2025 09:26:50 GMT
cache-control: public, max-age=3600
age: 1926
last-modified: Sat, 28 Jun 2025 00:47:12 GMT
etag: W/"b55394ed2f274eea5d528cf6c91e1dcf"
content-type: text/html
vary: Accept-Encoding
content-length: 26178

[26178 bytes of HTML]

GET /static/css/main.9e7d1ce5.css HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:141.0) Gecko/20100101 Firefox/141.0
Accept: text/css,*/*;q=0.1
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br, zstd

HTTP/1.1 200 OK
content-encoding: br
content-length: 43694
date: Mon, 30 Jun 2025 21:13:12 GMT
expires: Mon, 30 Jun 2025 21:47:29 GMT
cache-control: public, max-age=31536000
age: 42704
last-modified: Mon, 30 Jun 2025 00:33:45 GMT
etag: W/"d4f4d0955482844ad842986a9bcb7e8a"
content-type: text/css
vary: Accept-Encoding

[43694 bytes of CSS]

GET /static/js/main.a918a4e7.js HTTP/1.1
Host: developer.mozilla.org
…

建立 TCP 連線是客戶端-伺服器交換中成本高昂的一部分,而 TCP 慢啟動 意味著壽命更長的連線比新建立的連線更快。HTTP/1.1 允許您為多個請求和響應重用一個 TCP 連線,從而避免為每個請求建立新連線。然而,客戶端仍然必須等待每個資源下載完畢才能請求下一個資源(隊頭阻塞)。為了解決這個問題,大多數瀏覽器允許每個網站(或)最多有六個 TCP 連線。透過六個並行連線,瀏覽器可以使用 HTTP/1.1 模型同時獲取多個資源,這顯著提高了效能。

HTTP/1.1 最初於 1997 年 1 月作為 RFC 2068 釋出。

二十多年的發展

HTTP 的可擴充套件性使得建立新的頭和方法變得容易。儘管 HTTP/1.1 協議在兩次修訂中得到了完善,即 1999 年 6 月釋出的 RFC 2616 和在 HTTP/2 釋出之前於 2014 年 6 月釋出的 RFC 7230-RFC 7235,但它在 15 年多的時間裡一直非常穩定。HTTP/1.1 在 2022 年透過 RFC 9110 再次更新。HTTP 不僅更新了,而且所有的 HTTP 都被修訂,現在分為以下文件:語義 (RFC 9110)、快取 (RFC 9111) 適用於所有 HTTP 版本,以及 HTTP/1.1 (RFC 9112)、HTTP/2 (RFC 9113) 和 HTTP/3 (RFC 9114)。此外,該規範最終達到了網際網路標準 (STD 97) 的地位,而在此之前它一直是一個提議/草案標準。

使用 HTTP 進行安全傳輸

HTTP 的最大變化發生在 1994 年底。計算機服務公司 Netscape Communications 沒有在基本的 TCP/IP 棧上傳送 HTTP,而是在其之上建立了一個額外的加密傳輸層:SSL。SSL 1.0 從未向公眾釋出,但 SSL 2.0 及其後續版本 SSL 3.0 允許建立電子商務網站。為此,它們加密並保證了伺服器和客戶端之間交換訊息的真實性。SSL 最終被標準化併成為 TLS。

在同一時期,加密傳輸層的重要性變得顯而易見。網路不再是一個主要由學術機構組成的網路,而是變成了一個廣告商、隨機個人和犯罪分子爭奪儘可能多私人資料的“叢林”。隨著基於 HTTP 構建的應用程式變得更加強大,並需要訪問私人資訊,如地址簿、電子郵件和使用者位置,TLS 在電子商務用例之外也變得必要。

將 HTTP 用於複雜應用程式

蒂姆·伯納斯-李最初並未將 HTTP 設想為只讀媒體。他希望建立一個人們可以在遠端新增和移動文件的網路——一種分散式檔案系統。大約在 1996 年,HTTP 被擴充套件以允許創作,並建立了一個名為 WebDAV 的標準。它發展到包括特定應用程式,如用於處理地址簿條目的 CardDAV 和用於處理日曆的 CalDAV。但所有這些 *DAV 擴充套件都有一個缺陷:它們只有在伺服器實現時才可用。

2000 年,設計了一種使用 HTTP 的新模式:表述性狀態轉移(或 REST)。API 不基於新的 HTTP 方法,而是依賴於使用基本的 HTTP/1.1 方法訪問特定的 URI。這允許任何 Web 應用程式透過 API 檢索和修改其資料,而無需更新瀏覽器或伺服器。所有必要的資訊都嵌入在網站透過標準 HTTP/1.1 提供的檔案中。REST 模型的缺點是每個網站都定義了自己的非標準 RESTful API 並對其擁有完全控制權。這與客戶端和伺服器可以互操作的 *DAV 擴充套件不同。RESTful API 在 2010 年代變得非常普遍。

自 2005 年以來,更多的 API 可用於網頁。其中一些 API 為特定目的建立了 HTTP 協議的擴充套件:

  • 伺服器傳送事件,伺服器可以將偶爾的訊息推送到瀏覽器。
  • WebSocket,一種可以透過升級現有 HTTP 連線來設定的新協議。

放寬 Web 的安全模型

HTTP 獨立於 Web 安全模型,即 同源策略。事實上,當前的 Web 安全模型是在 HTTP 建立之後才發展起來的!多年來,在某些限制下解除該策略的一些限制被證明是有用的。伺服器使用一組新的 HTTP 頭將解除這些限制的程度和時間傳輸給客戶端。這些在 跨域資源共享 (CORS) 和 內容安全策略 (CSP) 等規範中定義。

除了這些大型擴充套件之外,還添加了許多其他頭,有時只是實驗性的。值得注意的頭包括用於控制隱私的 Do Not Track (DNT) 頭、X-Frame-OptionsUpgrade-Insecure-Requests,但還有更多。

HTTP/2 – 更高效能的協議

多年來,網頁變得越來越複雜。其中一些甚至本身就是應用程式。顯示了更多的視覺媒體,增加互動性的指令碼的數量和大小也增加了。透過更多的 HTTP 請求傳輸了更多的資料,這給 HTTP/1.1 連線帶來了更多的複雜性和開銷。為了解決這個問題,Google 在 2010 年代早期實施了一個實驗性協議 SPDY。這種客戶端和伺服器之間交換資料的替代方式吸引了瀏覽器和伺服器開發人員的興趣。SPDY 定義了響應能力的提高,並解決了重複資料傳輸的問題,為 HTTP/2 協議奠定了基礎。

HTTP/2 協議與 HTTP/1.1 有以下幾點不同:

  • 它是一個二進位制協議而不是文字協議。它不能手動讀取和建立。儘管有這個障礙,它允許實施改進的最佳化技術。
  • 它是一個多路複用協議。可以在同一連線上進行並行請求,消除了 HTTP/1.x 協議的限制。
  • 它壓縮頭。由於這些頭在一組請求中通常相似,這消除了資料傳輸的重複和開銷。

HTTP/2 於 2015 年 5 月正式標準化,其使用率在 2022 年 1 月達到峰值,佔所有網站的 46.9%(請參閱這些統計資料)。高流量網站為了節省資料傳輸開銷和隨後的預算,表現出最快的採用速度。

這種快速採用很可能是因為 HTTP/2 不需要更改網站和應用程式。要使用它,只需要一個與最新瀏覽器通訊的最新伺服器。只需要有限的群體來推動採用,隨著舊版瀏覽器和伺服器的更新,使用率自然會增加,而無需 Web 開發人員進行大量工作。

HTTP/2 之後的演變

HTTP 的可擴充套件性仍在用於新增新功能。值得注意的是,我們可以引用 2016 年出現的 HTTP 協議新擴充套件:

  • Alt-Svc 的支援允許將給定資源的標識與位置分離。這意味著更智慧的 CDN 快取機制。
  • 引入 客戶端提示 允許瀏覽器或客戶端主動將其要求和硬體限制資訊傳達給伺服器。
  • Cookie 頭中引入安全相關字首有助於保證安全 cookie 不會被篡改。

HTTP/3 - 基於 QUIC 的 HTTP

HTTP 的下一個主要版本 HTTP/3 與早期版本的 HTTP 具有相同的語義,但傳輸層部分使用 QUIC 而不是 TCP。截至 2022 年 10 月,所有網站的 26% 都在使用 HTTP/3

QUIC 旨在為 HTTP 連線提供更低的延遲。像 HTTP/2 一樣,它是一個多路複用協議,但 HTTP/2 執行在單個 TCP 連線上,因此在 TCP 層處理的丟包檢測和重傳可能會阻塞所有流。QUIC 在 UDP 上執行多個流,併為每個流獨立實現丟包檢測和重傳,因此如果發生錯誤,只有包含該資料包的流會被阻塞。

RFC 9114 中定義,HTTP/3 受到大多數主流瀏覽器的支援,包括 Chromium(及其變體,如 Chrome 和 Edge)和 Firefox。

另見