【計算機網路筆記】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

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

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。
  • 運作流程:
    1. 客戶端發起與伺服器的 TCP 連線(預設 port 80)。
    2. 一旦連線建立,瀏覽器(Client 端)和伺服器(Server 端)透過 Socket 介面傳送 HTTP 訊息。
    3. 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 張圖片,這時候設計者面臨一個重大的抉擇:

  1. 非持續性(Non-Persistent):每傳一張圖片,就建立一次連線,傳完馬上掛斷。
  2. 持續性(Persistent):建立一次連線後,保持通話,把所有圖片都傳完再掛斷。

術語解析

  • 來回時間(Round-Trip Time, RTT):
    • 物理時間單位。
    • 指的是一個小封包從客戶端發出,到達伺服器,再回到客戶端所需的總時間。
    • 包含了訊號傳播、路由器排隊及處理的時間。
  • 三次握手(Three-Way Handshake):TCP 建立連線的標準動作。
    1. 客戶端傳送一小段 TCP 區段給伺服器端。
    2. 伺服器端確認並回應一小段 TCP 區段。
    3. 客戶端再次回復確認給伺服器端。
    • 注意:該過程本身需消耗時間,通常視為 1 個 RTT 的開銷。

接下來下節(非持續性跟持續性連線)會以該範例做推演:一個網頁包含 1 個基礎 HTML 檔,以及裡面引用的 10 張 JPEG 圖片。

非持續性連線(Non-Persistent Connections)

HTTP/1.0 的預設行為。

運作流程:

  1. 建立連線:瀏覽器(HTTP 客戶端行程)向伺服器發起 TCP 連線(Server: port 80),伴隨 TCP 連線,客戶端與伺服端各開啟一個 socket。
  2. 發送請求:連線成功後,瀏覽器透過其 socket 發送 HTTP 請求(例如要 home.index)。
  3. 回傳資料:HTTP 伺服器行程收到請求,從其儲存裝置(RAM 或磁碟)取出檔案,封裝在 HTTP 回應訊息中透過 socket 傳回。
  4. 通知關閉:HTTP 伺服器行程告知 TCP 關閉 TCP 連線。(但在客戶端確認收到前,連線還不會真正斷開)
  5. 接收與解析:瀏覽器收到 HTML(回應訊息),TCP 連線終止,另外發現裡面有 10 張 JPEG 物件的連結。
  6. 重複步驟:對這 10 張 JPEG 物件,瀏覽器必須重複前四個步驟 10 次。

image

Image Source:Computer Networking: A Top-Down Approach (8th ed., p. 130, Figure 2.7)

效能計算:傳輸一個物件到底要多久?

  • TCP 握手:需要 11RTT\text{RTT}
  • HTTP 請求/回應:需要 11RTT\text{RTT}(請求過去,檔案頭回來)。
  • 檔案傳輸時間:假設為 TtransT_\text{trans}

總時間 = 2RTT+Ttrans2 \text{RTT} + T_\text{trans}

非持續性連線缺點(Drawbacks):

  1. 時間浪費:每個物件都要賠上 22 個 RTT 的延遲,使用者體驗很差。
  2. 資源浪費:伺服器必須為每一個微小的請求分配 TCP 緩衝區和變數,對伺服器 CPU 是沉重的負擔。

為了緩解非持續性連線造成的等待,瀏覽器可能會使用平行連線(平行數通常受限制)來同時下載多個資源,但這主要是把延遲重疊起來,並沒有消除每個物件都要重建連線帶來的固定開銷。

持續性連線(Persistent Connections)

此為 HTTP/1.1 的預設模式。

運作模式

伺服器在發送回應後,保持 TCP 連線開啟,後續在相同客戶端與伺服端之間的請求和回應,皆可透過同一筆連線來傳送。

如:後續的請求(上例中為基礎的 HTML 檔與 10 張圖片)直接沿用這一筆已經建好的、持續性的 TCP 連線做傳送即可。

兩種模式

  1. 非管線化(Without Pipelining):客戶端發送一個請求,等收到回應後,再發下一個。
  2. 管線化(With Pipelining):物件的請求可以連續送出,不須等待還沒處理完的請求得到回應。就是客戶端不用管回應是否回來,就能一直發送物件請求。

優勢

  • 省時:除了第一次建立連線外,後續物件只需要 1 個 RTT(甚至更少,如果是管線化)就能抓到。
  • 省力:伺服器不需反覆開關連線,節省 CPU 與記憶體資源。

2.2.3 HTTP Message Format(HTTP 訊息格式)

什麼是 HTTP 訊息格式?

HTTP 協定規定了兩種訊息類型:

  1. 請求訊息(Request Message):由客戶端(瀏覽器)發送給伺服器,告訴伺服器說我要什麼。
  2. 回應訊息(Response Message):由伺服器發回給客戶端,包含請求的結果(網頁內容或錯誤訊息)。

術語解析

  • 請求行(Request Line):HTTP 請求訊息的第一行,包含了三個資訊:
    1. 方法(Method)
    2. 網址(URL)
    3. HTTP 版本。
    • 生活比喻:就像去餐廳點餐說的第一句話:「我要一份 A 餐,外帶。」
  • 標頭行(Header Lines):緊跟在第一行之後的資訊,用來補充說明請求或回應的細節(例如:用什麼瀏覽器、偏好的語言)。
    • 生活比喻:如點餐後的備註:「薯條加大、大可去冰,我有載具。」
  • 資料主體(Entity Body):訊息的主要內容,在請求中,可能是用戶所填寫的表單資料,在回應中,就是用戶所看到的網頁 HTML 或圖片資料。
  • 狀態碼(Status Code):伺服器回應中的一個數字代碼,用來表示請求的處理結果(成功、失敗、找不到檔案等)。

HTTP 請求訊息(Request Message)

一個典型的 HTTP 請求訊息結構如下:

1
2
3
4
5
GET /somedir/page.html HTTP/1.1
Host: www.someschool.edu
Connection: close
User-agent: Mozilla/5.0
Accept-language: fr

解析:

  1. 請求行(Request Line)(第一行):
    • Method(方法):最常見的是 GET(請求獲取物件),其他還有:
      • POST(提交表單資料)
      • HEAD(只請求標頭,不拿內容,常用於除錯(Debug))
      • PUT(上傳物件)
      • DELETE(刪除物件)。
    • URL:請求的資源路徑,例如 /somedir/page.html
    • Version:使用的 HTTP 版本,例如 HTTP/1.1
  2. 標頭行(Header Lines)(後續幾行):
    • Host:指定主機名稱,在 Web 快取(Web Caching)中非常重要。(2.2.5 節)
    • Connection:告訴伺服器連線方式,
      • close 表示請求完就斷線(非持續性)
      • keep-alive 表示保持連線(持續性)。
    • User-agent:瀏覽器類型(例如 Mozilla/5.0),伺服器可根據這個資訊回傳適合不同瀏覽器版本的網頁。
    • Accept-language:使用者偏好的語言(例如 fr 代表法文),這是內容協商的一種。
  3. 空行:標頭行結束後,必須有一個空行(Carriage Return(回車)+ Line Feed(換行)),作為分隔。
  4. 資料主體(Entity Body):
    • 在使用 GET 方法時,這一塊通常是空的。
    • 在使用 POST 方法時(例如填寫搜尋關鍵字或登入表單),使用者輸入的資料會放在這裡傳給伺服器。
    • (註:雖 POST 是提交資料的標準方式,但我們常看到的網址如 www.somesite.com/animalsearch?monkeys&bananas 其實是用了 GET 方法,將資料直接附在 URL 後面傳送)

下圖為 HTTP 請求的訊息格式:

image

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
2
3
4
5
6
7
8
9
HTTP/1.1 200 OK
Connection: close
Date: Tue, 18 Aug 2015 15:44:04 GMT
Server: Apache/2.2.3 (CentOS)
Last-Modified: Tue, 18 Aug 2015 15:11:03 GMT
Content-Length: 6821
Content-Type: text/html

(data data data data data ...)

解析:

  1. 狀態行(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)。
  2. 標頭行(Header Lines):
    • Connectionclose 告訴客戶端傳完這個訊息後就會關閉 TCP 連線。
    • Date:非物件建立的時間,而是伺服器產生並發送這個回應訊息的時間。
    • Server:伺服器軟體類型(如 Apache),類似客戶端的 User-agent
    • Last-Modified:物件最後修改時間,對快取機制(Cache)極為重要,無論本地客戶端的物件快取或網路快取伺服器。
    • Content-Length:物件的大小(位元組)。
    • Content-Type:物件的類型(如 text/html),瀏覽器依此決定如何顯示內容(是網頁還是圖片)。
  3. 資料主體(Entity Body):此為我們所想要的,即網頁的 HTML 原始碼或圖片的二進位資料。

下圖為 HTTP 回應的訊息格式:

image

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 就像是病歷卡或號碼牌,再次進診間時,醫生能馬上調出其資料。

術語解析

  1. HTTP 回應標頭:伺服器發給瀏覽器的「識別證」。
  2. HTTP 請求標頭:瀏覽器之後每次發請求時,主動出示的「識別證」。
  3. Cookie 檔案:儲存在使用者端(電腦/手機)上,由瀏覽器管理的小檔案。
  4. 後端資料庫(Back-end Database):伺服器端真正儲存的資料(如購物車內容、帳戶資訊)的地方。

說例

假設有位使用者 Susan 第一次訪問 Amazon 網站,則其運作流程:

步驟動作方行為描述HTTP 訊息範例
1. 初次請求客戶端(Susan)Susan 的瀏覽器發送請求給 Amazon。此時他還沒有 ID。GET / HTTP/1.1
Host: www.amazon.com
2. 建立身分伺服端(Amazon)Amazon 收到請求,生成一個唯一的識別碼(ID),例如 1678,並在其後端資料庫建立一筆記錄。(Server 內部運作)
3. 回傳 Cookies伺服端(Amazon)伺服器在 HTTP 回應中加入 Set-cookie 標頭,告訴瀏覽器其代號是 1678。HTTP/1.1 200 OK
Set-cookie: 1678
4. 儲存 Cookie客戶端(Susan)瀏覽器收到回應,將 amazon: 1678 寫入 Susan 電腦裡的 Cookie 檔案。(Browser 內部運作)
5. 後續請求客戶端(Susan)一週後 Susan 再來,瀏覽器發現有 Amazon 的 Cookie,自動在請求中加入 Cookie 標頭。GET /cart HTTP/1.1
Cookie: 1678
6. 識別身分伺服端(Amazon)Amazon 看到 Cookie: 1678,去資料庫查詢 1678 是誰,並取出他的購物車或推薦清單。(Server 內部運作)

註:書中先假設 Susan 先前已拜訪過 ebay,因此會有 ebay 的 cookie。

image

Image Source:Computer Networking: A Top-Down Approach (8th ed., p. 136, Figure 2.10)

  1. 身分識別(Authorization):例如登入 Web 信箱後,伺服器透過 Cookie 知道你是已登入狀態。
  2. 購物車(Shopping Carts):Amazon 不需要知道你的真實名字,只需透過 Cookie ID(如 1678)就能追蹤你放入了哪些商品,最後再一次結帳。
  3. 推薦系統(Recommendations):網站根據 Cookie ID 記錄你的瀏覽歷史,從而推薦你可能感興趣的商品。
  4. 使用者會談層(User Session Layer):在無狀態的 HTTP 之上,建立一個邏輯上的會談(Session)。

:::info
註:會談(或稱會話、工作階段,Session)是指伺服端用來在一段特定時間內,記住並追蹤特定使用者互動狀態的一種機制。
:::

雖然 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 快取主要解決了兩個核心問題:

  1. 降低回應時間(Response Time):透過從「較近」的快取伺服器取得資料,大幅減少使用者等待的時間。
  2. 減少網路流量(Traffic Reduction):減少進出網際網路的重複流量,對於頻寬有限的機構(如大學、公司)來說,能省下巨額的頻寬費用並避免擁塞。

術語解析

  • 代理伺服器(Proxy Server / Web Cache):
    • 有自己的磁碟儲存空間,儲存最近被請求過的物件副本。
    • 具有雙重身分:
      • 對瀏覽器來說它是伺服器。
      • 對原始網站來說它是客戶端。
  • 原始伺服器(Origin Server):真正存放網頁原始檔案的伺服器(例如 Google 或 Amazon 的主機)。
  • 存取連結(Access Link):連接機構內部區域網路(LAN)與外部網際網路(Internet)的那條線路,通常是頻寬的瓶頸所在。
  • 複習:流量強度(Traffic Intensity):衡量網路擁塞程度的指標。
    • 公式:LaR\frac{La}{R}LL=封包長度,aa=封包到達佇列的平均速率,RR=連結傳輸速率)
    • 當此值接近 1 時,延遲會趨近無限大。

運作流程

當使用者的瀏覽器設定了 Web 快取後,所有的 HTTP 請求都會先導向快取伺服器:

  1. 攔截請求:瀏覽器向 Web 快取發送 HTTP 請求。
  2. 檢查快取:Web 快取檢查本地是否有該物件的副本。
    • 命中(Hit):如果有,直接回傳給瀏覽器(速度極快)。
    • 未命中(Miss):如果沒有,Web 快取會向原始伺服器發起 TCP 連線,請求該物件。
  3. 儲存並轉發:Web 快取收到物件後,會在本地存一份副本,然後將副本傳送給瀏覽器。

效能計算範例

情境:

  • 機構網路:高速區域網路(LAN),頻寬 100 Mbps。
  • 存取連結(Access Link):連接 Internet 的頻寬僅 15 Mbps。
  • 網路流量:每秒有 15 個請求(req/s),每個物件平均大小 1 Mbits。
  • Internet 延遲:假設從路由器出去到伺服器再回來,平均需要 2 秒。

image

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×1.0=0.6= 0.6 \times 1.0=0.6
  • 當流量強度為 0.6 時,排隊延遲非常小(可忽略不計)。
  • 總平均延遲計算:0.4×(0.01 s)+0.6×(2.01 s)=1.21 s0.4 \times (0.01 \ s) + 0.6 \times (2.01 \ s) = 1.21 \ s
  • 結果:比直接升級頻寬還快(因為 40% 的資料是秒開),而且不用花大錢升級線路。

有條件的 GET(Conditional GET)

快取雖然好,但有一個致命問題:

如果伺服器上的資料更新了,快取卻給了舊資料怎麼辦?HTTP 使用有條件的 GET(Conditional GET)來解決這個問題。

  • 機制:當快取伺服器想確認資料是否過期時,會發送一個帶有 If-Modified-Since: 標頭的請求。
  • 伺服器回應:
    1. 若資料已更新:回傳新資料(HTTP 200 OK)。
    2. 若資料沒變:伺服器只回傳一個簡單的訊號,不包含物件內容。

運作方式舉例

  1. 代理快取代表發出請求的瀏覽器,傳一筆請求訊息給伺服器:
1
2
GET /fruit/kiwi.gif HTTP/1.1
Host: www.exotiquecuisine.com
  1. 網站伺服器會將含有所請求物件的回應訊息傳給快取:
1
2
3
4
5
6
7
HTTP/1.1 200 OK
Date: Sat, 3 Oct 2015 15:39:29
Server: Apache/1.3.0 (Unix)
Last-Modified: Wed, 9 Sep 2015 09:23:24
Content-Type: image/gif

(data data data data data ...)

而快取伺服器會將物件轉送給發出請求的瀏覽器,同時也將該物件快取於本機上。

快取也會一併儲存物件最後修改的日期。

  1. 一個禮拜後,另一個瀏覽器也透過快取請求同一物件,而該物件仍然在快取中。

該物件在過去可能已在網站伺服器中被改過,因此快取會發出有條件的 GET 做最新資料的查核,如:

1
2
3
GET /fruit/kiwi.gif HTTP/1.1
Host: www.exotiquecuisine.com
If-modified-since: Wed, 9 Sep 2015 09:23:24

可發現 If-modified-since: 標頭行的值(日期)與一星期前伺服器送出的 Last-Modified: 值是相同的。

有條件的 GET 在於告訴伺服器,只在當指定日期後的該物件有被修改過,才需要傳送此物件。

  1. 假設該物件從 9 Sep 2015 09:23:24 後從未被修改過,則網站伺服器會傳送一則回應訊息給快取。
1
2
3
4
5
HTTP/1.1 304 Not Modified
Date: Sat, 10 Oct 2015 15:39:29
Server: Apache/1.3.0 (Unix)

(empty entity body)

回應有條件的 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)。

  • 運作機制:
    1. 拆解:當伺服器要傳送 HTTP 回應時,訊框子層會把訊息拆碎,標頭變成「標頭訊框」,內容變成多個「資料訊框」。
    2. 交錯傳輸(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.cssscript.js

在之前 HTTP/1 會做以下流程:

  • 伺服器回傳 HTML -> 瀏覽器解析 HTML -> 瀏覽器發現缺檔案 -> 瀏覽器請求 CSS/JS -> 伺服器回傳。
  • 這樣多了一個來回的延遲(RTT)。

而推播模式下:

  • 伺服器回傳 HTML 的同時,順便把 style.cssscript.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

Image Source:https://www.geeksforgeeks.org/javascript/what-is-url-uniform-resource-locator/

HTTP 與 TCP 的關係

HTTP 不處理可靠性,而是:

  • 建立於 TCP 之上
  • 使用 TCP 提供之:
    • 可靠傳輸
    • 正確順序
    • 遺失重傳等功能。

HTTP 運作流程為:

  1. 建立 TCP 連線(三次握手)
  2. 透過 socket 傳送 HTTP 訊息
  3. 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 浪費
  • 節省資源。

兩種模式:

  1. 非管線化(Without Pipelining):等收到回應再發下一個。
  2. 管線化(With Pipelining):可連續發送請求。

HTTP 訊息格式

HTTP 定義兩種訊息:

  1. Request(請求)
  2. Response(回應)

Request 結構

1
2
3
4
5
6
GET /index.html HTTP/1.1
Host: example.com
Header: value

(空行)
(可能的資料主體)

組成:

  • Request Line(方法 + URL + 版本)
  • Header Lines
  • 空行
  • Entity Body(例如 POST 資料)。

常見方法:

  • GET
  • POST
  • HEAD
  • PUT
  • DELETE

Response 結構

1
2
3
4
HTTP/1.1 200 OK
Header: value

(資料內容)

包含:

  • Status Line(版本 + 狀態碼)
  • Header Lines
  • Entity Body

常見狀態碼:

  • 200 OK
  • 301 Moved
  • 400 Bad Request
  • 404 Not Found
  • 505 Not Supported

Cookies:在無狀態上建立狀態

HTTP 本身無狀態,但網站需要:

  • 登入維持
  • 購物車
  • 推薦系統。

Cookies 的機制:

  1. 伺服器回應加入 Set-Cookie
  2. 瀏覽器儲存 Cookie
  3. 後續請求自動附上 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 請求都會先導向快取伺服器:

  1. 攔截請求:瀏覽器向 Web 快取發送 HTTP 請求。
  2. 檢查快取:Web 快取檢查本地是否有該物件的副本。
    • 命中(Hit):如果有,直接回傳給瀏覽器(速度極快)。
    • 未命中(Miss):如果沒有,Web 快取會向原始伺服器發起 TCP 連線,請求該物件。
  3. 儲存並轉發:Web 快取收到物件後,會在本地存一份副本,然後將副本傳送給瀏覽器。

效能改善

  • 降低存取連結流量
  • 降低平均延遲
  • 成本遠低於升級頻寬。

有條件的 GET(Conditional GET)

避免快取資料過期問題:

  • 當快取伺服器想確認資料是否過期時,會發送一個帶有 If-Modified-Since: 標頭的請求。
  • 伺服器回應:
    1. 若資料已更新:回傳新資料(HTTP 200 OK)。
    2. 若資料沒變:伺服器只回傳一個簡單的訊號,不包含物件內容。

HTTP/2:解決效能瓶頸

HTTP/1.1 問題:隊首阻塞(Head-of-Line Blocking)

大檔案卡住,小檔案無法先送。

HTTP/2 的改進

  1. 二進位訊框(Binary Framing)
    • 將 HTTP 訊息切成小的訊框(frame)。
    • 以二進位傳輸。
    • 更有效率。
  2. 多工(Multiplexing)
    • 單一 TCP 連線。
    • 多個物件同時交錯傳輸。
    • 消除隊首阻塞問題。
  3. 優先級(Priority)
    • 設定權重(1–256)。
    • 指定依賴關係。
    • 重要資源優先傳送。
  4. 伺服器推播(Server Push)
    • 伺服器回傳 HTML 的同時,順便把 CSS 和 JS 推播給瀏覽器。
    • 瀏覽器解析完 HTML 時,發現檔案已經在快取裡了,直接秒開。

整體總結

HTTP 發展可視為三階段優化(後續還有 HTTP/3 只是這篇沒講到):

階段解決問題
HTTP/1.0定義基本請求/回應機制
HTTP/1.1解決重複建立 TCP 的延遲
HTTP/2解決單連線阻塞問題

搭配:

  • Cookies 解決無狀態限制。
  • Web Cache 解決頻寬與延遲。
  • Conditional GET 解決資料一致性。