【計算機網路筆記】2.2 The Web and HTTP
【計算機網路筆記】2.2 The Web and HTTP
Hello Guys, I’m LukeTseng. 歡迎你也感謝你點入本篇文章,本系列主要讀本為《Computer Networking: A Top-Down Approach, 8th Edition》,就是計算機網路的聖經,會製作該系列也主要因為修課上會用到。若你喜歡本系列或本文,不妨動動你的手指,為這篇文章按下一顆愛心吧,或是追蹤我的個人公開頁也 Ok。
2.2.1 Overview of HTTP(HTTP 的概觀)
什麼是 HTTP?
HTTP(HyperText Transfer Protocol),中譯「超文本傳輸協定」,是 Web 的核心應用層協定。
它定義了客戶端(Client)和伺服器(Server)之間「如何對話」的規則。
也規定了訊息的結構(語法)以及交換訊息的方式(語義)。
為什麼需要 HTTP?
在 1990 年代初期,網際網路主要用於傳輸文字和文件。
為了讓這些文件(也稱為網頁,Web Pages)能在不同的電腦系統之間互相請求和傳送,需要一個通用的標準。
HTTP 即該標準,讓大家可用 Chrome 瀏覽器去存取由 Apache 架設的伺服器,而不必擔心作業系統不相容的問題。

Image Source:Computer Networking: A Top-Down Approach (8th ed., p. 127, Figure 2.6)
術語解析
- 網頁(Web Page / Document):一個網頁並不是單一的一個檔案,而是由一個基礎 HTML 檔和數個物件(Objects)組成的集合體。
- 物件(Object):指一個單獨的檔案,例如 HTML 檔、JPEG 圖片、Java 小程式或影片片段。每個物件都可以透過一個網址(URL)單獨被存取。
- URL(Uniform Resource Locator,統一資源定位符):即為網址。主要分為
- 主機名稱(Hostname 或是域名 Domain name)
- 路徑(Path)
如下圖:
- Scheme 對應
https,稱為通訊協定。- 說明:告訴瀏覽器使用哪種協定來存取資源,例如 HTTPS、HTTP、FTP 等。
- Authority(包含 Domain Name 和 Port),稱為授權單位。
- 說明:包含網域名稱與埠號的組合。
- Domain Name 對應
www.geeksforgeeks.org,稱為域名。- 說明:伺服器的位址。
- Port 對應
:80,稱為通訊埠號、端口。- 說明:伺服器上的特定通道,Web 預設通常是 80(HTTP) 或 443(HTTPS)。
- Path to the File 對應
/array-data-structure,稱為路徑名稱或檔案路徑。- 說明:資源在伺服器上的具體位置或路由。
- Query 對應
?,稱為查詢(起始符號)。- 說明:問號
?用來分隔路徑與查詢參數。
- 說明:問號
- Parameters 對應
ref=home-articlecards,稱為參數。- 說明:傳遞給伺服器的額外資訊,通常是鍵值對(Key-Value)的形式。
- Fragment 對應
#what-is-array,稱為錨點。- 說明:指向網頁內部的特定位置(例如跳轉到頁面的某個標題)。

Image Source:https://www.geeksforgeeks.org/javascript/what-is-url-uniform-resource-locator/
- 網頁瀏覽器(Web Browser):在 HTTP 術語中,為客戶端(Client),由它發起請求並顯示網頁。
- 網頁伺服器(Web Server):為伺服器 (Server),負責儲存 Web 物件,並回應客戶端的請求。
HTTP 與 TCP 的關係
HTTP 並不負責資料傳輸的可靠性,這個責任是下層的傳輸層(Transport Layer)要負的。
- 依賴協定:HTTP 使用 TCP 作為底層支撐,而非 UDP。
- 運作流程:
- 客戶端發起與伺服器的 TCP 連線(預設 port 80)。
- 一旦連線建立,瀏覽器(Client 端)和伺服器(Server 端)透過 Socket 介面傳送 HTTP 訊息。
- TCP 提供可靠資料傳輸服務,保證資料不遺失、順序正確。
HTTP 協定本身不需要設計「資料遺失重傳」的機制,因為 TCP 已經做好了。
無狀態協定(Stateless Protocol)
HTTP 即為一種無狀態協定。
定義:伺服器不會保存關於客戶端過去請求的任何資訊。
例子:如果在 5 秒內跟伺服器要了兩次同一個檔案,伺服器會重新再傳送一次檔案。就是伺服器不會記住之前給了客戶端什麼檔案。
為什麼要設計成無狀態?請見下表:
| 特性 | 無狀態(Stateless) - HTTP | 有狀態(Stateful) |
|---|---|---|
| 設計複雜度 | 低。伺服器不需要維護客戶端的歷史紀錄。 | 高。伺服器需要維護並管理大量歷史資訊。 |
| 資源消耗 | 低。處理完請求即可釋放資源。 | 高。需消耗記憶體儲存狀態。 |
| 錯誤恢復 | 容易。如果伺服器當機重啟,不會影響後續請求(因為本來就沒記住什麼)。 | 困難。若伺服器當機,必須設法恢復之前的狀態,否則通訊會錯亂。 |
註:雖然 HTTP 本身是無狀態的,但現代網站通常會透過 Cookies 來模擬狀態,在後面的 2.2.4 節會提到。
2.2.2 Non-Persistent and Persistent Connections(非持續性與持續性連線)
問題的根源:HTTP 是跑在 TCP 之上的,表示在傳送任何資料(網頁內容)前,客戶端(Client)和伺服器(Server)必須先「握手」建立連線。
情境:一個網頁不只有文字,還有 10 張圖片,這時候設計者面臨一個重大的抉擇:
- 非持續性(Non-Persistent):每傳一張圖片,就建立一次連線,傳完馬上掛斷。
- 持續性(Persistent):建立一次連線後,保持通話,把所有圖片都傳完再掛斷。
術語解析
- 來回時間(Round-Trip Time, RTT):
- 物理時間單位。
- 指的是一個小封包從客戶端發出,到達伺服器,再回到客戶端所需的總時間。
- 包含了訊號傳播、路由器排隊及處理的時間。
- 三次握手(Three-Way Handshake):TCP 建立連線的標準動作。
- 客戶端傳送一小段 TCP 區段給伺服器端。
- 伺服器端確認並回應一小段 TCP 區段。
- 客戶端再次回復確認給伺服器端。
- 注意:該過程本身需消耗時間,通常視為 1 個 RTT 的開銷。
接下來下節(非持續性跟持續性連線)會以該範例做推演:一個網頁包含 1 個基礎 HTML 檔,以及裡面引用的 10 張 JPEG 圖片。
非持續性連線(Non-Persistent Connections)
HTTP/1.0 的預設行為。
運作流程:
- 建立連線:瀏覽器(HTTP 客戶端行程)向伺服器發起 TCP 連線(Server: port 80),伴隨 TCP 連線,客戶端與伺服端各開啟一個 socket。
- 發送請求:連線成功後,瀏覽器透過其 socket 發送 HTTP 請求(例如要 home.index)。
- 回傳資料:HTTP 伺服器行程收到請求,從其儲存裝置(RAM 或磁碟)取出檔案,封裝在 HTTP 回應訊息中透過 socket 傳回。
- 通知關閉:HTTP 伺服器行程告知 TCP 關閉 TCP 連線。(但在客戶端確認收到前,連線還不會真正斷開)
- 接收與解析:瀏覽器收到 HTML(回應訊息),TCP 連線終止,另外發現裡面有 10 張 JPEG 物件的連結。
- 重複步驟:對這 10 張 JPEG 物件,瀏覽器必須重複前四個步驟 10 次。

Image Source:Computer Networking: A Top-Down Approach (8th ed., p. 130, Figure 2.7)
效能計算:傳輸一個物件到底要多久?
- TCP 握手:需要 個 。
- HTTP 請求/回應:需要 個 (請求過去,檔案頭回來)。
- 檔案傳輸時間:假設為
總時間 =
非持續性連線缺點(Drawbacks):
- 時間浪費:每個物件都要賠上 個 RTT 的延遲,使用者體驗很差。
- 資源浪費:伺服器必須為每一個微小的請求分配 TCP 緩衝區和變數,對伺服器 CPU 是沉重的負擔。
為了緩解非持續性連線造成的等待,瀏覽器可能會使用平行連線(平行數通常受限制)來同時下載多個資源,但這主要是把延遲重疊起來,並沒有消除每個物件都要重建連線帶來的固定開銷。
持續性連線(Persistent Connections)
此為 HTTP/1.1 的預設模式。
運作模式
伺服器在發送回應後,保持 TCP 連線開啟,後續在相同客戶端與伺服端之間的請求和回應,皆可透過同一筆連線來傳送。
如:後續的請求(上例中為基礎的 HTML 檔與 10 張圖片)直接沿用這一筆已經建好的、持續性的 TCP 連線做傳送即可。
兩種模式
- 非管線化(Without Pipelining):客戶端發送一個請求,等收到回應後,再發下一個。
- 管線化(With Pipelining):物件的請求可以連續送出,不須等待還沒處理完的請求得到回應。就是客戶端不用管回應是否回來,就能一直發送物件請求。
優勢
- 省時:除了第一次建立連線外,後續物件只需要 1 個 RTT(甚至更少,如果是管線化)就能抓到。
- 省力:伺服器不需反覆開關連線,節省 CPU 與記憶體資源。
2.2.3 HTTP Message Format(HTTP 訊息格式)
什麼是 HTTP 訊息格式?
HTTP 協定規定了兩種訊息類型:
- 請求訊息(Request Message):由客戶端(瀏覽器)發送給伺服器,告訴伺服器說我要什麼。
- 回應訊息(Response Message):由伺服器發回給客戶端,包含請求的結果(網頁內容或錯誤訊息)。
術語解析
- 請求行(Request Line):HTTP 請求訊息的第一行,包含了三個資訊:
- 方法(Method)
- 網址(URL)
- HTTP 版本。
- 生活比喻:就像去餐廳點餐說的第一句話:「我要一份 A 餐,外帶。」
- 標頭行(Header Lines):緊跟在第一行之後的資訊,用來補充說明請求或回應的細節(例如:用什麼瀏覽器、偏好的語言)。
- 生活比喻:如點餐後的備註:「薯條加大、大可去冰,我有載具。」
- 資料主體(Entity Body):訊息的主要內容,在請求中,可能是用戶所填寫的表單資料,在回應中,就是用戶所看到的網頁 HTML 或圖片資料。
- 狀態碼(Status Code):伺服器回應中的一個數字代碼,用來表示請求的處理結果(成功、失敗、找不到檔案等)。
HTTP 請求訊息(Request Message)
一個典型的 HTTP 請求訊息結構如下:
1 | GET /somedir/page.html HTTP/1.1 |
解析:
- 請求行(Request Line)(第一行):
- Method(方法):最常見的是 GET(請求獲取物件),其他還有:
- POST(提交表單資料)
- HEAD(只請求標頭,不拿內容,常用於除錯(Debug))
- PUT(上傳物件)
- DELETE(刪除物件)。
- URL:請求的資源路徑,例如
/somedir/page.html。 - Version:使用的 HTTP 版本,例如
HTTP/1.1。
- Method(方法):最常見的是 GET(請求獲取物件),其他還有:
- 標頭行(Header Lines)(後續幾行):
Host:指定主機名稱,在 Web 快取(Web Caching)中非常重要。(2.2.5 節)Connection:告訴伺服器連線方式,close表示請求完就斷線(非持續性)keep-alive表示保持連線(持續性)。
User-agent:瀏覽器類型(例如Mozilla/5.0),伺服器可根據這個資訊回傳適合不同瀏覽器版本的網頁。Accept-language:使用者偏好的語言(例如fr代表法文),這是內容協商的一種。
- 空行:標頭行結束後,必須有一個空行(Carriage Return(回車)+ Line Feed(換行)),作為分隔。
- 資料主體(Entity Body):
- 在使用
GET方法時,這一塊通常是空的。 - 在使用
POST方法時(例如填寫搜尋關鍵字或登入表單),使用者輸入的資料會放在這裡傳給伺服器。 - (註:雖 POST 是提交資料的標準方式,但我們常看到的網址如
www.somesite.com/animalsearch?monkeys&bananas其實是用了 GET 方法,將資料直接附在 URL 後面傳送)
- 在使用
下圖為 HTTP 請求的訊息格式:

Image Source:Computer Networking: A Top-Down Approach (8th ed., p. 132, Figure 2.8)
- sp 為 space,即空白。
- cr 為 Carriage Return,即回車。
- lf 為 Line Feed,即換行。
HTTP 回應訊息(Response Message)
伺服器收到請求後,會回傳如下的訊息:
1 | HTTP/1.1 200 OK |
解析:
- 狀態行(Status Line)(第一行):
- Version:HTTP 版本,如
HTTP/1.1。 - Status Code(狀態碼):常見代碼如下:
200 OK:成功,請求的物件包含在訊息中。301 Moved Permanently:物件已永久移動,新的 URL 會在標頭中給出。400 Bad Request:請求語法錯誤、格式錯誤、參數異常或無效的路由,導致伺服器無法理解或處理該請求。404 Not Found:伺服器找不到你請求的文件。505 HTTP Version Not Supported:伺服器不支援你用的 HTTP 版本。
- Phrase:狀態碼的文字說明(如
OK, Not Found)。
- Version:HTTP 版本,如
- 標頭行(Header Lines):
Connection:close告訴客戶端傳完這個訊息後就會關閉 TCP 連線。Date:非物件建立的時間,而是伺服器產生並發送這個回應訊息的時間。Server:伺服器軟體類型(如 Apache),類似客戶端的User-agent。Last-Modified:物件最後修改時間,對快取機制(Cache)極為重要,無論本地客戶端的物件快取或網路快取伺服器。Content-Length:物件的大小(位元組)。Content-Type:物件的類型(如text/html),瀏覽器依此決定如何顯示內容(是網頁還是圖片)。
- 資料主體(Entity Body):此為我們所想要的,即網頁的 HTML 原始碼或圖片的二進位資料。
下圖為 HTTP 回應的訊息格式:

Image Source:Computer Networking: A Top-Down Approach (8th ed., p. 134, Figure 2.9)
2.2.4 User-Server Interaction: Cookies(使用者與伺服器的互動:Cookie)
上節(2.2.3)學到了 HTTP 訊息的格式,也強調了一個重點:HTTP 是一個無狀態(Stateless)協定,表示伺服器不會記住客戶端的狀態。
該節將揭示 Web 如何在無狀態的基礎上,建立起有狀態(Stateful)的互動。
但在 Amazon 或蝦皮網購時,為何伺服器能記得購物車裡放了什麼?為什麼不用每次點擊頁面都重新登入?答案是 Cookies 這個東西,相信大多數人也常見到網站要叫你同意 Cookies。
Cookies 允許網站在使用者的電腦上儲存少量資料,讓伺服器能夠跨越多個請求來追蹤或識別使用者。
來做個比喻:
- HTTP 請求就像去掛號看病。
- 如果沒有病歷表(Cookies),每次看醫生就都會問「你是誰?哪裡不舒服?」,完全不記得你五分鐘前才剛量過血壓。
- Cookies 就像是病歷卡或號碼牌,再次進診間時,醫生能馬上調出其資料。
術語解析
- HTTP 回應標頭:伺服器發給瀏覽器的「識別證」。
- HTTP 請求標頭:瀏覽器之後每次發請求時,主動出示的「識別證」。
- Cookie 檔案:儲存在使用者端(電腦/手機)上,由瀏覽器管理的小檔案。
- 後端資料庫(Back-end Database):伺服器端真正儲存的資料(如購物車內容、帳戶資訊)的地方。
說例
假設有位使用者 Susan 第一次訪問 Amazon 網站,則其運作流程:
| 步驟 | 動作方 | 行為描述 | HTTP 訊息範例 |
|---|---|---|---|
| 1. 初次請求 | 客戶端(Susan) | Susan 的瀏覽器發送請求給 Amazon。此時他還沒有 ID。 | GET / HTTP/1.1Host: www.amazon.com |
| 2. 建立身分 | 伺服端(Amazon) | Amazon 收到請求,生成一個唯一的識別碼(ID),例如 1678,並在其後端資料庫建立一筆記錄。 | (Server 內部運作) |
| 3. 回傳 Cookies | 伺服端(Amazon) | 伺服器在 HTTP 回應中加入 Set-cookie 標頭,告訴瀏覽器其代號是 1678。 | HTTP/1.1 200 OKSet-cookie: 1678 |
| 4. 儲存 Cookie | 客戶端(Susan) | 瀏覽器收到回應,將 amazon: 1678 寫入 Susan 電腦裡的 Cookie 檔案。 | (Browser 內部運作) |
| 5. 後續請求 | 客戶端(Susan) | 一週後 Susan 再來,瀏覽器發現有 Amazon 的 Cookie,自動在請求中加入 Cookie 標頭。 | GET /cart HTTP/1.1Cookie: 1678 |
| 6. 識別身分 | 伺服端(Amazon) | Amazon 看到 Cookie: 1678,去資料庫查詢 1678 是誰,並取出他的購物車或推薦清單。 | (Server 內部運作) |
註:書中先假設 Susan 先前已拜訪過 ebay,因此會有 ebay 的 cookie。

Image Source:Computer Networking: A Top-Down Approach (8th ed., p. 136, Figure 2.10)
Cookie 的用途
- 身分識別(Authorization):例如登入 Web 信箱後,伺服器透過 Cookie 知道你是已登入狀態。
- 購物車(Shopping Carts):Amazon 不需要知道你的真實名字,只需透過 Cookie ID(如 1678)就能追蹤你放入了哪些商品,最後再一次結帳。
- 推薦系統(Recommendations):網站根據 Cookie ID 記錄你的瀏覽歷史,從而推薦你可能感興趣的商品。
- 使用者會談層(User Session Layer):在無狀態的 HTTP 之上,建立一個邏輯上的會談(Session)。
:::info
註:會談(或稱會話、工作階段,Session)是指伺服端用來在一段特定時間內,記住並追蹤特定使用者互動狀態的一種機制。
:::
Cookie 隱私權擔憂
雖然 Cookies 提供了方便的購物體驗(例如 One-click shopping),但也引發了隱私爭議。
問題:網站可以結合 Cookies 和使用者提供的個資(姓名、信用卡),將 ID(1678)與真實身分綁定,並記錄你所有的瀏覽行為。
風險:這些資料可能被收集並賣給第三方,導致你在網路上的一舉一動都被監視。
所以現在有很多網站會提示要不要用 Cookie,原因就在這裡。
2.2.5 Web Caching(Web 快取)
什麼是 Web 快取
Web 快取(Web Cache),又常被稱為代理伺服器(Proxy Server)。
為一個位於客戶端和原始伺服器(Origin Server)之間的中介網路實體。
簡單來說,Web 快取就像是校園裡的超商。
如果超商(Cache)有我們想要的飲料(資料),就不用大老遠跑到外面的超商(Origin Server)去買,既省時又省力。
為何需要 Web 快取
Web 快取主要解決了兩個核心問題:
- 降低回應時間(Response Time):透過從「較近」的快取伺服器取得資料,大幅減少使用者等待的時間。
- 減少網路流量(Traffic Reduction):減少進出網際網路的重複流量,對於頻寬有限的機構(如大學、公司)來說,能省下巨額的頻寬費用並避免擁塞。
術語解析
- 代理伺服器(Proxy Server / Web Cache):
- 有自己的磁碟儲存空間,儲存最近被請求過的物件副本。
- 具有雙重身分:
- 對瀏覽器來說它是伺服器。
- 對原始網站來說它是客戶端。
- 原始伺服器(Origin Server):真正存放網頁原始檔案的伺服器(例如 Google 或 Amazon 的主機)。
- 存取連結(Access Link):連接機構內部區域網路(LAN)與外部網際網路(Internet)的那條線路,通常是頻寬的瓶頸所在。
- 複習:流量強度(Traffic Intensity):衡量網路擁塞程度的指標。
- 公式: (=封包長度,=封包到達佇列的平均速率,=連結傳輸速率)
- 當此值接近 1 時,延遲會趨近無限大。
運作流程
當使用者的瀏覽器設定了 Web 快取後,所有的 HTTP 請求都會先導向快取伺服器:
- 攔截請求:瀏覽器向 Web 快取發送 HTTP 請求。
- 檢查快取:Web 快取檢查本地是否有該物件的副本。
- 命中(Hit):如果有,直接回傳給瀏覽器(速度極快)。
- 未命中(Miss):如果沒有,Web 快取會向原始伺服器發起 TCP 連線,請求該物件。
- 儲存並轉發:Web 快取收到物件後,會在本地存一份副本,然後將副本傳送給瀏覽器。
效能計算範例
情境:
- 機構網路:高速區域網路(LAN),頻寬 100 Mbps。
- 存取連結(Access Link):連接 Internet 的頻寬僅 15 Mbps。
- 網路流量:每秒有 15 個請求(req/s),每個物件平均大小 1 Mbits。
- Internet 延遲:假設從路由器出去到伺服器再回來,平均需要 2 秒。

Image Source:Computer Networking: A Top-Down Approach (8th ed., p. 140, Figure 2.12)
LAN 的流量強度:$$\frac{15 \text{ req/s} \times 1 \text{ Mbits/req}}{100 \text{ Mbps}} = 0.15$$
由於 LAN 的流量強度只有 0.15,通常最多只會造成十幾毫秒的延遲,因此可忽略其延遲。
存取連結(網際網路路由器到機構路由器)上的流量強度:$$\frac{15 \text{ req/s} \times 1 \text{ Mbits/req}}{15 \text{ Mbps}} = 1$$
情況 A:沒有快取
- 存取連結流量強度 = 1。
- 當流量強度趨近於 1 時,排隊延遲會變得非常龐大(數分鐘甚至更久)。
- 結果:網頁根本打不開,使用者體驗極差。
情況 B:升級頻寬
- 升級存取連結的頻寬至 100 Mbps。
- 其流量強度降至 0.15,延遲消失,主要只剩 Internet 的 2 秒延遲。
- 結果:速度變快,但成本非常昂貴。
情況 C:安裝 Web 快取
- 假設快取的命中率為 0.4(40%)。
- 這表示 40% 的請求由內部 LAN 解決(幾毫秒),只有 60% 的請求需要通過那條擁擠的存取連結。
- 由於有 60% 請求經過存取連結,其新的流量強度 。
- 當流量強度為 0.6 時,排隊延遲非常小(可忽略不計)。
- 總平均延遲計算:
- 結果:比直接升級頻寬還快(因為 40% 的資料是秒開),而且不用花大錢升級線路。
有條件的 GET(Conditional GET)
快取雖然好,但有一個致命問題:
如果伺服器上的資料更新了,快取卻給了舊資料怎麼辦?HTTP 使用有條件的 GET(Conditional GET)來解決這個問題。
- 機制:當快取伺服器想確認資料是否過期時,會發送一個帶有
If-Modified-Since:標頭的請求。 - 伺服器回應:
- 若資料已更新:回傳新資料(HTTP 200 OK)。
- 若資料沒變:伺服器只回傳一個簡單的訊號,不包含物件內容。
運作方式舉例
- 代理快取代表發出請求的瀏覽器,傳一筆請求訊息給伺服器:
1 | GET /fruit/kiwi.gif HTTP/1.1 |
- 網站伺服器會將含有所請求物件的回應訊息傳給快取:
1 | HTTP/1.1 200 OK |
而快取伺服器會將物件轉送給發出請求的瀏覽器,同時也將該物件快取於本機上。
快取也會一併儲存物件最後修改的日期。
- 一個禮拜後,另一個瀏覽器也透過快取請求同一物件,而該物件仍然在快取中。
該物件在過去可能已在網站伺服器中被改過,因此快取會發出有條件的 GET 做最新資料的查核,如:
1 | GET /fruit/kiwi.gif HTTP/1.1 |
可發現 If-modified-since: 標頭行的值(日期)與一星期前伺服器送出的 Last-Modified: 值是相同的。
有條件的 GET 在於告訴伺服器,只在當指定日期後的該物件有被修改過,才需要傳送此物件。
- 假設該物件從
9 Sep 2015 09:23:24後從未被修改過,則網站伺服器會傳送一則回應訊息給快取。
1 | HTTP/1.1 304 Not Modified |
回應有條件的 GET 時,網站伺服器仍然會送出回應訊息,但不會在回應訊息中包含所請求的物件。
若包含所請求的物件,則會浪費頻寬、增加使用者感受的回應時間,特別當物件很大時。
304 Not Modified 狀態行為用於告知快取可繼續進行處理,將代理快取的物件副本轉送給發出請求的瀏覽器。
2.2.6 HTTP/2
什麼是 HTTP/2
HTTP/2 是 HTTP 協定的第二個主要版本。
它的主要目標是在不改變 HTTP 既有語義(方法、狀態碼、URL、標頭欄位)的前提下,透過改變資料的「格式」與「傳輸方式」來大幅降低延遲。
為什麼需要 HTTP/2?
先前 HTTP/1.1 的問題是隊首阻塞(Head of Line, HOL)。
什麼是隊首阻塞?用一個例子說明:
- 假設一個網頁有一個很大的影片檔,後面跟著 8 個很小的圖片檔。
- 在 HTTP/1.1 的單一 TCP 連線中,這些物件必須排隊傳送
- 如果大影片檔案卡在最前面,後面的小圖片就必須等它傳完才能動。
這就像在超市結帳,如果只買了一瓶水,但前面的人推了一整車日用品,只能乾等。
舊時代的解法:瀏覽器為了繞過這個問題,會同時開啟多個(通常是 6 個)平行 TCP 連線。
解法的缺點:對伺服器來說是巨大的負擔(要維護多個 Socket),而且會干擾 TCP 的壅塞控制(Congestion Control)機制,讓瀏覽器不公平地佔用頻寬。
HTTP/2 的誕生,就是為了在單一 TCP 連線下解決這個阻塞問題。
術語解析
- 多工傳輸(Multiplexing):允許在同一個 TCP 連線上,同時傳輸多個請求和回應的資料,彼此穿插而不互相干擾。
- 訊框(Frame):HTTP/2 通訊的最小單位。在 HTTP/2 中,HTTP 訊息(Message)被拆解成更小的二進位格式的訊框。
- 二進位訊框處理(Binary Framing):HTTP/1.1 是文字格式(人類可讀),HTTP/2 則是二進位格式(電腦讀得快、錯誤少、體積小)。
- 伺服器推播(Server Push):伺服器在客戶端還沒請求之前,就主動把客戶端「將來會用到」的物件推播過去。
HTTP/2 訊框處理與交錯傳輸(Framing & Interleaving)
HTTP/2 最重要的創新是引入了訊框子層(Framing Sub-layer)。
- 運作機制:
- 拆解:當伺服器要傳送 HTTP 回應時,訊框子層會把訊息拆碎,標頭變成「標頭訊框」,內容變成多個「資料訊框」。
- 交錯傳輸(Interleaving):來自不同物件的訊框可在同一條連線上混合著傳送。
- 解決 HOL 阻塞的實例:以前面的例子說明,假設要傳送 1 個大影片(切成 1000 個訊框)和 8 個小物件(每個切成 2 個訊框)。
- 沒有交錯(HTTP/1.1):小物件必須等影片的 1000 個訊框全傳完才能開始傳。
- 有交錯(HTTP/2):
- 伺服器可以先傳 1 個影片訊框,然後馬上穿插傳送那 8 個小物件的訊框。
- 結果:小物件可以非常快地傳完並顯示,使用者在體感上不會覺得網頁卡住了。
訊息優先級(Prioritization)
既然可交錯傳輸,順序由誰決定?HTTP/2 允許開發者自定義優先級(Priority)。
- 權重(Weights):客戶端可給每個請求分配一個 1 到 256 的權重。
- 相依性(Dependency):客戶端可以指定某個訊息「依賴」於另一個訊息(例如:先傳完 HTML 再傳 CSS)。
- 伺服器行為:伺服器會根據這些權重和依賴關係,決定先發送哪些訊框,確保重要的內容(如網頁結構)最先到達。
伺服器推播(Server Push)
此為 HTTP/2 的優化。
假設當伺服器收到 index.html 的請求,它解析後發現這個網頁肯定需要 style.css 和 script.js。
在之前 HTTP/1 會做以下流程:
- 伺服器回傳 HTML -> 瀏覽器解析 HTML -> 瀏覽器發現缺檔案 -> 瀏覽器請求 CSS/JS -> 伺服器回傳。
- 這樣多了一個來回的延遲(RTT)。
而推播模式下:
- 伺服器回傳 HTML 的同時,順便把
style.css和script.js推播給瀏覽器。 - 這樣瀏覽器解析完 HTML 時,發現檔案已經在快取裡了,直接秒開。
總整理
HTTP 的概觀
HTTP 是什麼?
HTTP(HyperText Transfer Protocol)是 Web 的應用層協定,負責規範:
- 客戶端與伺服器如何交換訊息
- 訊息的格式(語法)
- 訊息的意義(語義)
- 它解決的是「如何請求與傳送網頁資源」的問題。
HTTP 的設計背景
為了讓不同系統(不同作業系統、不同瀏覽器與伺服器軟體)能互通,HTTP 提供一個通用標準,使:
- Chrome 可以存取 Apache
- Windows 可以連 Linux 主機
- 不需考慮底層平台差異。
網頁的組成
一個網頁並非單一檔案,而是:
- 1 個基礎 HTML
- 多個物件(圖片、影片、CSS、JS)
每個物件都由 URL 唯一定位。
URL 結構包含:
- Scheme(協定,如 HTTP/HTTPS)
- Domain(主機名稱)
- Port(埠號)
- Path(資源路徑)
- Query(查詢參數)
- Fragment(頁面內定位)

Image Source:https://www.geeksforgeeks.org/javascript/what-is-url-uniform-resource-locator/
HTTP 與 TCP 的關係
HTTP 不處理可靠性,而是:
- 建立於 TCP 之上
- 使用 TCP 提供之:
- 可靠傳輸
- 正確順序
- 遺失重傳等功能。
HTTP 運作流程為:
- 建立 TCP 連線(三次握手)
- 透過 socket 傳送 HTTP 訊息
- TCP 負責底層傳輸保證。
無狀態協定(Stateless)
HTTP 不會記住過去請求。
優點:
- 設計簡單
- 資源消耗低
- 容錯能力強(伺服器重啟不影響)
缺點:
- 無法直接實現登入、購物車等功能
缺點部分解決方案為:Cookies。
連線模式:非持續性與持續性連線
問題核心:TCP 建立有成本。
每次建立 TCP 需 1 個 RTT(Round Trip Time)。
非持續性連線(HTTP/1.0)
每個物件都依照以下運作流程:
- 建立連線
- 傳送資料
- 關閉連線。
時間成本: $$2 \text{RTT} + T_\text{trans}$$
若有 1 頁面 + 10 圖片,則需要重複 11 次上述流程。
缺點:
- 延遲極高
- 伺服器負擔重。
持續性連線(HTTP/1.1)
建立一次 TCP,傳送所有物件。
優點:
- 只需 1 次握手
- 減少 RTT 浪費
- 節省資源。
兩種模式:
- 非管線化(Without Pipelining):等收到回應再發下一個。
- 管線化(With Pipelining):可連續發送請求。
HTTP 訊息格式
HTTP 定義兩種訊息:
- Request(請求)
- Response(回應)
Request 結構
1 | GET /index.html HTTP/1.1 |
組成:
- Request Line(方法 + URL + 版本)
- Header Lines
- 空行
- Entity Body(例如 POST 資料)。
常見方法:
- GET
- POST
- HEAD
- PUT
- DELETE
Response 結構
1 | HTTP/1.1 200 OK |
包含:
- Status Line(版本 + 狀態碼)
- Header Lines
- Entity Body
常見狀態碼:
- 200 OK
- 301 Moved
- 400 Bad Request
- 404 Not Found
- 505 Not Supported
Cookies:在無狀態上建立狀態
HTTP 本身無狀態,但網站需要:
- 登入維持
- 購物車
- 推薦系統。
Cookies 的機制:
- 伺服器回應加入 Set-Cookie
- 瀏覽器儲存 Cookie
- 後續請求自動附上 Cookie
伺服器透過 Cookie ID 查詢後端資料庫。
在無狀態的 HTTP 之上,實質上 Cookies 是建立使用者會談層(User Session Layer)。
Cookies 風險:
- 可與個資綁定
- 可追蹤瀏覽行為
- 可能涉及隱私問題
Web 快取(Web Caching)
當中所面臨的核心問題:存取連結壅塞。
Web 快取(Web Cache),又常被稱為代理伺服器(Proxy Server)。
Web Cache 的作用
核心功能:透過儲存網頁資源的複本(如圖片、HTML、JS 檔案),來減少重複下載的需求。
位於:
- Client ↔ Cache ↔ Origin Server
運作流程
當使用者的瀏覽器設定了 Web 快取後,所有的 HTTP 請求都會先導向快取伺服器:
- 攔截請求:瀏覽器向 Web 快取發送 HTTP 請求。
- 檢查快取:Web 快取檢查本地是否有該物件的副本。
- 命中(Hit):如果有,直接回傳給瀏覽器(速度極快)。
- 未命中(Miss):如果沒有,Web 快取會向原始伺服器發起 TCP 連線,請求該物件。
- 儲存並轉發:Web 快取收到物件後,會在本地存一份副本,然後將副本傳送給瀏覽器。
效能改善
- 降低存取連結流量
- 降低平均延遲
- 成本遠低於升級頻寬。
有條件的 GET(Conditional GET)
避免快取資料過期問題:
- 當快取伺服器想確認資料是否過期時,會發送一個帶有
If-Modified-Since:標頭的請求。 - 伺服器回應:
- 若資料已更新:回傳新資料(HTTP 200 OK)。
- 若資料沒變:伺服器只回傳一個簡單的訊號,不包含物件內容。
HTTP/2:解決效能瓶頸
HTTP/1.1 問題:隊首阻塞(Head-of-Line Blocking)
大檔案卡住,小檔案無法先送。
HTTP/2 的改進
- 二進位訊框(Binary Framing)
- 將 HTTP 訊息切成小的訊框(frame)。
- 以二進位傳輸。
- 更有效率。
- 多工(Multiplexing)
- 單一 TCP 連線。
- 多個物件同時交錯傳輸。
- 消除隊首阻塞問題。
- 優先級(Priority)
- 設定權重(1–256)。
- 指定依賴關係。
- 重要資源優先傳送。
- 伺服器推播(Server Push)
- 伺服器回傳 HTML 的同時,順便把 CSS 和 JS 推播給瀏覽器。
- 瀏覽器解析完 HTML 時,發現檔案已經在快取裡了,直接秒開。
整體總結
HTTP 發展可視為三階段優化(後續還有 HTTP/3 只是這篇沒講到):
| 階段 | 解決問題 |
|---|---|
| HTTP/1.0 | 定義基本請求/回應機制 |
| HTTP/1.1 | 解決重複建立 TCP 的延遲 |
| HTTP/2 | 解決單連線阻塞問題 |
搭配:
- Cookies 解決無狀態限制。
- Web Cache 解決頻寬與延遲。
- Conditional GET 解決資料一致性。
