從輸入 URL 到網頁渲染:瀏覽器如何載入網頁
本文詳細解析了當使用者在瀏覽器輸入 URL 後,從 DNS 解析到網頁最終渲染的完整流程,涵蓋關鍵技術步驟、性能優化考量以及安全性實務。本文結構旨在幫助開發者,尤其是準備技術面試的開發者,深入理解端到端流程並能簡潔表達。
流程總覽 (End-to-End Flow)
當使用者輸入 URL,瀏覽器會進行 DNS 解析取得 IP 位址,建立 TCP/TLS 連線,發送 HTTP 請求。伺服器處理後回傳 HTTP 回應,瀏覽器解析 HTML、CSS 和 JavaScript,生成 DOM 和 CSSOM,完成佈局與繪製,最終呈現網頁,並處理後續使用者互動與請求。
1. 從輸入 URL 到 DNS 解析
一切從使用者輸入 URL(例如 https://www.example.com/path?x=1#fragment
)開始。瀏覽器會解析 URL 的組成部分:scheme、host、port、path、query、fragment。
DNS 查找流程 (Domain Name Lookup)
瀏覽器將域名轉換為 IP 位址,查找順序如下:
瀏覽器快取:檢查瀏覽器本地快取記錄。
OS hosts 檔案:檢查作業系統的 hosts 檔案。
本地 DNS 解析器:向本地 DNS 伺服器查詢。
ISP 或公共 DNS:進行遞迴查詢(如 Google 8.8.8.8)。
DNS 紀錄類型 | 說明 |
A/AAAA | 最終返回 IPv4 或 IPv6 位址。 |
CNAME | 需額外查詢,會增加延遲。 |
面試關鍵句:DNS 將域名映射為 IP,是應用層到網路層的轉換,直接影響首次載入的延遲(DNS lookup time)。
2. 連線建立:TCP 三次握手與 TLS 握手
在取得 IP 後,瀏覽器與伺服器建立連線,分為 TCP 和(若為 HTTPS)TLS 兩個階段。
TCP 三次握手 (Handshake)
確保可靠傳輸:
SYN:客戶端發送同步封包。
SYN/ACK:伺服器回應確認並發送自己的序列號。
ACK:客戶端確認,完成連線建立。
TLS 握手(HTTPS)
建立安全通道,防止竊聽與中間人攻擊:
ClientHello:發送支持的加密算法。
ServerHello + Certificate:回傳選擇的算法與數位憑證。
Key Exchange:雙方協商對稱加密金鑰。
Finished:確認安全連線建立。
性能優化: TLS 1.3 透過減少往返次數(如 0-RTT 模式),顯著提升連線建立性能。
3. HTTP 請求:格式、方法與重要標頭
連線建立後,瀏覽器發送 HTTP 請求。
常見 HTTP 方法與特性
方法 | 用途 | 特性 |
GET | 獲取資源 | 安全(Safe)、可快取、冪等(Idempotent) |
POST | 提交資料 | 用於創建或修改資源 |
PUT | 更新資源 | 冪等(可重複執行) |
DELETE | 刪除資源 | 冪等 |
重要請求標頭
Host:目標域名。
Accept:客戶端接受的內容類型。
User-Agent:瀏覽器/客戶端資訊。
Connection:如
keep-alive
,保持連線。Cookie:傳送會話資訊。
Cache-Control、If-Modified-Since、ETag:控制快取行為。
Authorization:用於身份驗證(如 Bearer Token)。
4. 伺服器處理與回應
伺服器處理請求,生成回應。
伺服器處理流程
路由:匹配 URL path 到處理程序。
中介軟體:處理日誌、認證、限流等。
控制器/處理程序:執行業務邏輯(如資料庫查詢)。
渲染/序列化:生成回應內容(如 HTML 或 JSON)。
動靜分離:靜態資源(圖片、CSS)通常由 CDN 提供,動態頁面由應用伺服器生成。
HTTP 狀態碼重點
類別 | 狀態碼 | 說明 | 面試區分點 |
2xx 成功 | 200 OK | 請求成功。 | - |
3xx 重定向 | 301 | 永久重定向(瀏覽器快取)。 | 區分 301 (永久) vs 302 (臨時)。 |
4xx 客戶端錯誤 | 404 | 資源未找到。 | 區分 401 (未授權) vs 403 (禁止訪問)。 |
401/403 | 身份驗證失敗 / 權限不足。 | 429 (過多請求) 適用於限流場景。 | |
5xx 伺服器錯誤 | 500 | 伺服器內部錯誤。 | - |
5. 瀏覽器解析與渲染管線 (Critical Rendering Path)
伺服器回傳回應後,瀏覽器啟動渲染流程:
解析 HTML
DOM (Document Object Model)
載入 CSS
CSSOM (CSS Object Model)
合成 Render Tree:結合 DOM 與 CSSOM,排除不可見元素。
佈局 (Layout/Reflow):計算元素的位置與大小。
繪製 (Paint):將元素轉為像素。
合成 (Compositing):將圖層合併顯示到螢幕。
JavaScript 對渲染的影響
同步
<script>
:阻塞 HTML 解析,延遲渲染。async
/defer
:非同步載入或延遲執行,改善性能。
網路協定與性能
HTTP/1.1:限制並行連線(通常 6 個/域名)。
HTTP/2:支持多路複用 (Multiplexing),減少連線開銷。
HTTP/3:基於 QUIC,進一步降低延遲。
關鍵渲染路徑:目標是最小化阻塞資源(CSS 和同步 JS),加速 首次內容繪製 (FCP) 與 最大內容繪製 (LCP)。
6. 性能、快取、安全與觀測:延伸知識點
快取策略 (Caching)
策略 | 標頭範例 | 說明 |
強快取 | Cache-Control: max-age=3600 | 直接使用本地快取,不發送請求。 |
協商快取 | ETag / If-None-Match 或 Last-Modified / If-Modified-Since | 發送請求,伺服器驗證資源是否更新(若未更新回傳 304 Not Modified)。 |
認證與授權 (AuthN & AuthZ)
Cookie + Session:傳統會話管理,需設置
HttpOnly
(防 XSS)、Secure
(僅 HTTPS)、SameSite
(防 CSRF)。JWT (JSON Web Token):無狀態認證,適合 API。
OAuth:授權第三方應用訪問資源。
安全防護 (Security)
CORS:跨來源資源共享,處理 OPTIONS 預檢請求。
CSRF (跨站請求偽造):使用 CSRF Token 或
SameSite
Cookie 屬性。XSS (跨站腳本攻擊):對用戶輸入進行輸出編碼。
觀測與除錯 (Monitoring & Debugging)
工具:Chrome DevTools (Network/Performance)、
curl
、Postman、Wireshark。性能指標:
TTFB (Time to First Byte):伺服器處理請求的時間。
FCP / LCP:首次/最大內容繪製時間。
CLS (Cumulative Layout Shift):佈局偏移穩定性。
面試亮點:提及具體優化措施,如啟用 gzip/brotli 壓縮、使用 CDN、延遲載入 (Lazy Loading) 圖片、DNS Prefetch、減少 TLS 握手次數。
7. 面試回答範例 (30–45 秒精練)
範例 1(概述重點)
「使用者輸入 URL 後,流程始於 DNS 解析獲取 IP,接著建立 TCP 與 TLS 連線。然後發送 HTTP 請求,伺服器處理後回傳 HTTP 回應。瀏覽器收到後解析 HTML/CSS/JS,生成 DOM 和 CSSOM,最後執行佈局與繪製,完成網頁渲染。」
2. 範例 2(強調效能與安全)
「流程的關鍵環節是減少延遲與確保安全。性能優化涵蓋 DNS Prefetch、HTTP/2/3、CDN、壓縮、以及長短期快取。安全保障則涉及 TLS、HttpOnly/SameSite Cookie、CORS 與 CSRF 防護。優化成效可透過 TTFB、FCP、LCP 等指標驗證。」
結論
掌握從 DNS 解析、連線建立、HTTP 請求與回應、伺服器處理到瀏覽器渲染的每個關鍵步驟,熟悉重要標頭、狀態碼、性能優化與安全考量,並能使用具體指標(TTFB、FCP、LCP)與工具(DevTools、curl)進行驗證,即可在面試中展現技術深度與可信度。
什麼是 CORS?
CORS 是一種基於 HTTP 標頭的機制,允許瀏覽器去訪問不同來源 (Origin) 的資源。
它解決的是瀏覽器的一個核心安全政策:同源政策 (Same-Origin Policy, SOP)。
核心安全問題:同源政策 (SOP)
為了防止惡意網站竊取用戶在其他網站上的敏感資料,瀏覽器預設只允許請求和回應發生在同一個來源下。
一個「來源」由三個部分決定:
協定 (Protocol):例如
http
或https
。網域名稱 (Host):例如
www.example.com
或api.service.net
。通訊埠 (Port):例如
80
或443
。
📌 範例:
https://app.com:443
請求https://app.com:443
→ 同源
https://app.com:443
請求http://app.com:443
→ 不同源 (協定不同)
https://app.com:443
請求https://api.app.com:443
→ 不同源 (網域不同)
當網頁發出一個跨來源的請求時,瀏覽器會自動阻止這個請求的回應被前端 JavaScript 讀取,除非伺服器明確表示允許。CORS 就是這個「明確允許」的機制。
CORS 運作機制
CORS 主要透過 HTTP 回應中的一個關鍵標頭來運作:Access-Control-Allow-Origin
。
1. 簡單請求 (Simple Requests)
如果請求滿足特定條件(例如:只使用 GET
、HEAD
或 POST
方法,且 Content-Type
僅限於特定的三種格式),瀏覽器會直接發送請求。
瀏覽器請求: 在請求標頭中自動加入
Origin: <來源>
,告訴伺服器「我來自哪裡」。伺服器回應: 伺服器在回應標頭中加入:
Access-Control-Allow-Origin: https://app.com
或
Access-Control-Allow-Origin: *
(允許所有來源)
如果瀏覽器檢查回應中的 Access-Control-Allow-Origin
標頭包含發出請求的來源,就會允許 JavaScript 讀取回應內容;否則,請求雖然發出去了,但瀏覽器會拋出錯誤並阻止程式碼存取資料。
2. 預檢請求 (Preflight Requests)
對於不符合「簡單請求」條件的請求(例如:使用了 PUT
或 DELETE
方法,或自定義了 HTTP 標頭),瀏覽器會在正式請求發送之前,先發送一個特殊的 OPTIONS
請求給伺服器。這稱為預檢 (Preflight)。
預檢的目的是:
詢問伺服器:是否允許來自這個來源 (
Origin
) 的請求?詢問伺服器:是否允許使用這個方法 (
Access-Control-Request-Method
)?詢問伺服器:是否允許使用這些自定義標頭 (
Access-Control-Request-Headers
)?
預檢成功: 伺服器在
OPTIONS
回應中明確告訴瀏覽器允許,瀏覽器才會發送第二次(真正的)請求。預檢失敗: 伺服器拒絕,瀏覽器直接取消後續的正式請求。
CORS 相關的重要標頭
標頭 | 類型 | 用途 |
Origin | 請求 | 瀏覽器發送,指示請求的來源 URL。 |
Access-Control-Allow-Origin | 回應 | 伺服器設定,指定允許存取的來源。 |
Access-Control-Allow-Methods | 回應 | 伺服器設定,指定允許的方法(GET, POST, PUT 等)。 |
Access-Control-Allow-Headers | 回應 | 伺服器設定,指定允許的自定義標頭。 |
Access-Control-Max-Age | 回應 | 伺服器設定,預檢請求結果可快取的秒數。 |
Access-Control-Allow-Credentials | 回應 | 伺服器設定,是否允許請求攜帶 Cookie。 |
總結來說: CORS 是一個「伺服器告知瀏覽器,我允許被誰存取」的機制,目的是在不犧牲同源政策安全性的前提下,實現跨來源的 API 呼叫。
沒有留言:
張貼留言