跳至主要內容
Skip to content

網路請求的一生:從輸入 URL 到頁面渲染

當你在瀏覽器的網址列輸入 https://example.com 並按下 Enter,看似簡單的動作背後,其實經歷了一連串精密的步驟。理解這個完整的流程,是掌握 HTTP 協定的第一步,也是最重要的一步。

本篇將帶你走過一個網路請求的「一生」,從 DNS 查詢到頁面渲染,讓你對整個過程有完整的認識。


一、 旅程總覽

在深入每個步驟之前,讓我們先看看完整的流程圖:

這個流程可以分為六大階段:

  1. URL 解析:瀏覽器解讀你輸入的網址
  2. DNS 查詢:將域名轉換為 IP 位址
  3. TCP 連線:與伺服器建立穩定的連線通道
  4. TLS 握手:建立加密的安全連線(HTTPS)
  5. HTTP 交換:發送請求、接收回應
  6. 頁面渲染:將收到的資料轉換為你看到的網頁

接下來,我們將深入每個階段。


二、 第一站:URL 解析

什麼是 URL?

URL(Uniform Resource Locator)是網路資源的「地址」。當你輸入 https://www.example.com:443/path/page?name=value#section 時,瀏覽器會將其拆解為以下組成部分:

https://www.example.com:443/path/page?name=value#section
  │         │           │     │         │          │
  │         │           │     │         │          └─ Fragment(片段)
  │         │           │     │         └─ Query String(查詢參數)
  │         │           │     └─ Path(路徑)
  │         │           └─ Port(埠號)
  │         └─ Host(主機名稱)
  └─ Scheme(協定)
組件說明範例
Scheme協定類型httpshttpftp
Host伺服器位址www.example.com
Port埠號(可省略)443(HTTPS 預設)、80(HTTP 預設)
Path資源路徑/path/page
Query查詢參數?name=value
Fragment頁面錨點#section

TIP

關於 URI、URL 與 URN 的詳細定義差異與網址結構解剖,可以參考:URI/URL/URN 完全指南:網位址的結構與奧秘

瀏覽器的預處理:在發出請求之前

當網址被解析完成後,瀏覽器並不會立刻衝向伺服器,而是會先執行一套「內部檢查」,以確保安全性並節省不必要的網路資源消耗。

1. HSTS 檢查:強迫加密通信

HSTS (HTTP Strict Transport Security) 是一種安全機制,告訴瀏覽器:「這個網站只能透過 HTTPS 訪問。」

  • 為什麼需要? 避免 SSL Strip (釣魚攻擊)。如果使用者手動輸入 http://,瀏覽器會查看內部的 HSTS 清單(如內建的 Preload List 或之前的快取)。
  • 結果:如果命中,瀏覽器會直接發動 307 Internal Redirect。這是一個在瀏覽器內部發生的轉向,完全沒有網路流量出去,直接將請求升級為 https://

TIP

關於 SSL Strip 的詳細運作原理與攻擊過程,可以參考這篇專題:深入淺出 SSL Strip:強行剝離加密層的中間人攻擊

2. 快取檢查:省下網路頻寬

瀏覽器會先看「我之前有沒有存過這項資源?」。它會檢查 Disk CacheMemory Cache 中的內容。

  • 強快取判斷:瀏覽器會解析 Cache-ControlExpires Header。
    • 命中 (Cache Hit):狀態碼顯示 200 OK (from disk cache)不會發生任何網路存取,速度極快。
    • 未命中:才進入下一步「DNS 查詢」。

TIP

「完美的請求,就是不發出請求。」 透過 HSTS 與快取檢查,瀏覽器在與外界溝通前就排除了大量安全隱患與頻寬浪費。


三、 第二站:DNS 查詢

為什麼需要 DNS?

電腦之間的通訊使用 IP 位址(如 93.184.216.34),但人類更容易記住域名(如 example.com)。DNS(Domain Name System)就是將域名轉換為 IP 位址的「電話簿」。

DNS 查詢的層級

DNS 查詢是一個逐層查找的過程,瀏覽器會按照以下順序尋找:

各層快取說明

層級位置TTL(存活時間)
瀏覽器快取Chrome/Firefox 內部通常 1 分鐘
作業系統快取系統層級依 DNS 記錄設定
路由器快取家用/公司路由器依設定而異
ISP DNS網路服務商依 DNS 記錄設定

DNS 記錄類型

DNS 不只回傳 IP 位址,它支援多種記錄類型:

記錄類型用途範例
AIPv4 位址93.184.216.34
AAAAIPv6 位址2606:2800:220:1:...
CNAME別名指向www.example.com → example.com
MX郵件伺服器mail.example.com
TXT文字資訊用於 SPF、DKIM 驗證
NS域名伺服器指定管理該域名的 DNS

> **冷知識**:為什麼 IPv6 的記錄叫 `AAAA` 而不是 `A6`?這是工程師式的幽默——IPv4 地址長度是 32 bits,IPv6 是 128 bits,剛好是 4 倍(128 ÷ 32 = 4),所以就把 A 寫了四次!

實際觀察 DNS 查詢

你可以使用命令列工具來觀察 DNS 查詢:

bash
# macOS / Linux
nslookup example.com

# 或使用 dig 獲得更詳細資訊
dig example.com

# 查詢特定記錄類型
dig example.com AAAA

輸出範例:

;; ANSWER SECTION:
example.com.    86400   IN  A   93.184.216.34

這表示 example.com 的 A 記錄指向 93.184.216.34,TTL 為 86400 秒(24 小時)。


四、 第三站:TCP 連線

為什麼是 TCP?

HTTP 建立在 TCP(Transmission Control Protocol)之上。TCP 提供:

  • 可靠傳輸:確保資料完整送達,遺失會重傳
  • 有序傳輸:資料按順序到達
  • 流量控制:避免發送方壓垮接收方

三向交握(Three-Way Handshake)

在發送任何 HTTP 資料之前,瀏覽器必須先與伺服器建立 TCP 連線。這個過程稱為「三向交握」:

TIP

關於 TCP 協定 的詳細機制、三向交握的深層意義以及如何優雅斷開連線,可以參考:深入淺出 TCP 協定:網路傳輸的可靠基石

各步驟詳解

步驟發送方內容意義
1. SYN客戶端seq=x請求建立連線,同步序列號
2. SYN-ACK伺服器seq=y, ack=x+1同意連線,確認收到 SYN
3. ACK客戶端ack=y+1確認收到伺服器的 SYN-ACK

TCP 封包結構(簡化)

┌─────────────────────────────────────────────────────┐
│  來源埠 (16 bits)  │  目的埠 (16 bits)              │
├─────────────────────────────────────────────────────┤
│              序列號 Sequence Number (32 bits)        │
├─────────────────────────────────────────────────────┤
│              確認號 Acknowledgment Number (32 bits)  │
├─────────────────────────────────────────────────────┤
│ 標誌位:SYN ACK FIN RST PSH URG │ 視窗大小           │
├─────────────────────────────────────────────────────┤
│              資料 (Payload)                          │
└─────────────────────────────────────────────────────┘

IMPORTANT

三向交握需要一個 RTT(Round-Trip Time,往返時間)。如果 RTT 是 50ms,光是建立 TCP 連線就需要至少 50ms。這就是為什麼 HTTP/2 和 HTTP/3 都致力於減少連線建立的開銷。


五、 第四站:TLS 握手

為什麼需要 TLS?

HTTP 是明文傳輸,任何中間節點(路由器、WiFi 熱點)都可以偷看或竄改內容。TLS(Transport Layer Security)為 HTTP 加上一層加密保護,形成 HTTPS。

NOTE

很多人會把加密稱為 SSL,但其實 SSL 是 TLS 的前身且已經過時。關於這兩者的歷史糾葛與命名由來,可以參考:SSL 與 TLS 的恩怨情仇:為什麼我們還在說 SSL?

TLS 提供三大保障:

  1. 加密:資料被加密,中間人無法讀取
  2. 完整性:資料無法被竄改
  3. 身份驗證:確認伺服器的真實身份

TLS 握手流程

TIP

關於 TLS 協定 的運作細節、憑證驗證機制以及 TLS 1.3 的加速革命,可以參考:深入淺出 TLS 協定:保護網路通訊的安全鎖

TLS 1.2 vs TLS 1.3

TLS 1.3 大幅簡化了握手流程:

特性TLS 1.2TLS 1.3
握手往返次數2 RTT1 RTT
0-RTT 支援✅(重連時)
廢棄的不安全算法仍支援已移除
握手加密部分明文完全加密

TIP

可以使用 openssl s_client -connect example.com:443 來查看網站使用的 TLS 版本和加密套件。


六、 第五站:HTTP 請求與回應

終於到了主角登場的時刻!在 TCP 連線建立(如果是 HTTPS,還要完成 TLS 握手)之後,瀏覽器就可以發送 HTTP 請求了。

HTTP 請求結構

一個標準的 HTTP 請求由三部分組成:

http
GET /index.html HTTP/1.1          ← 請求行(Request Line)
Host: www.example.com             ← 請求頭(Headers)
User-Agent: Mozilla/5.0 ...
Accept: text/html
Accept-Language: zh-TW
Accept-Encoding: gzip, deflate
Connection: keep-alive
                                  ← 空行
                                  ← 請求體(Body,GET 通常沒有)

請求行組成

GET /index.html HTTP/1.1
 │       │         │
 │       │         └─ HTTP 版本
 │       └─ 請求路徑(URI)
 └─ 請求方法(Method)

HTTP 回應結構

伺服器處理請求後,回傳 HTTP 回應:

http
HTTP/1.1 200 OK                   ← 狀態行(Status Line)
Date: Wed, 08 Jan 2025 10:00:00 GMT  ← 回應頭(Headers)
Content-Type: text/html; charset=UTF-8
Content-Length: 1256
Cache-Control: max-age=3600
                                  ← 空行
<!DOCTYPE html>                   ← 回應體(Body)
<html>
  <head>...</head>
  <body>...</body>
</html>

狀態碼分類

範圍類別說明
1xx資訊請求已接收,繼續處理
2xx成功請求成功處理
3xx重導向需要進一步操作
4xx客戶端錯誤請求有誤
5xx伺服器錯誤伺服器處理失敗

TIP

這些概念在後續文章會有更深入的探討。本篇的重點是讓你先對整體流程有個完整的認識。


七、 第六站:頁面渲染

當瀏覽器收到 HTML 回應後,渲染之旅才正式開始:

渲染流程詳解

階段說明
解析 HTML將 HTML 轉換為 DOM(Document Object Model)樹
解析 CSS將 CSS 轉換為 CSSOM(CSS Object Model)樹
建構 Render Tree結合 DOM 和 CSSOM,決定哪些元素要顯示
Layout計算每個元素的位置和大小
Paint繪製像素到各個圖層
Composite將多個圖層合成最終畫面

阻塞渲染的資源

並非所有資源都能平行載入,有些會阻塞渲染:

資源類型阻塞行為
CSS阻塞渲染(必須等 CSSOM 建構完成)
JavaScript阻塞 DOM 解析(除非加上 asyncdefer
圖片不阻塞渲染,但可能造成重新布局
字體可能造成 FOIT(Flash of Invisible Text)

八、 完整時間線

讓我們把所有階段放在一起,看看一個請求的完整時間線:

時間 →

├── DNS Lookup ──────────┤  (20-200ms)
│                        │
├── TCP Handshake ───────┤  (1 RTT, ~50ms)
│                        │
├── TLS Handshake ───────┤  (1-2 RTT, ~100ms)
│                        │
├── HTTP Request ────────┤  (發送時間,通常很短)
│                        │
├── Server Processing ───┤  (視後端複雜度)
│                        │
├── HTTP Response ───────┤  (視回應大小)
│                        │
├── Content Download ────┤  (視內容大小和頻寬)
│                        │
└── Rendering ───────────┘  (視頁面複雜度)

在 Chrome DevTools 的 Network 面板中,你可以看到這些階段的詳細時間:

Timing 名稱對應階段
Queueing請求排隊
Stalled等待可用連線
DNS LookupDNS 查詢
Initial connectionTCP 握手
SSLTLS 握手
Request sent發送請求
Waiting (TTFB)等待首位元組
Content Download下載內容

總結

一個看似簡單的網路請求,實際上經歷了六大階段:

階段關鍵技術耗時影響因素
URL 解析URI 規範幾乎不耗時
DNS 查詢DNS 協定快取命中率、DNS 伺服器距離
TCP 連線TCP 三向交握網路延遲(RTT)
TLS 握手TLS 1.2/1.3TLS 版本、是否重用 Session
HTTP 交換HTTP 協定請求/回應大小、伺服器處理時間
頁面渲染DOM/CSSOM頁面複雜度、資源數量

理解這個完整流程後,你會更清楚:

  • 為什麼 CDN 能加速網站(減少 RTT)
  • 為什麼 HTTP/2 比 HTTP/1.1 快(多路複用)
  • 為什麼 TLS 1.3 成為新標準(減少握手次數)
  • 為什麼 快取策略 如此重要(跳過大量步驟)

進階挑戰

  1. 實作挑戰:使用 Chrome DevTools 的 Network 面板,觀察你常用網站的請求時間線。找出 DNS Lookup、TCP 連線、TLS 握手各花了多少時間。

  2. 深度思考:為什麼在行動網路(4G/5G)上,網頁載入速度往往比有線網路慢?除了頻寬因素,還有什麼原因?(提示:RTT 與連線建立成本)

  3. 探索實驗:使用 curl -v https://example.com 命令,觀察完整的連線過程。找出 TLS 握手的詳細資訊。


延伸閱讀與資源