網址列按下 Enter 後,到底發生了什麼事?

如果你去面試 Web 工程師,十家大概有八家會問你這題:「當你在網址列輸入一段 URL 並按下 Enter 後,背後到底發生了什麼事?」
很多人會去背標準答案應付面試,但老實說,把這套流程刻在腦海裡,絕對不是為了考試。當有一天客戶打來狂吼:「網站掛了!白畫面!」,如果你懂這套流程,你就不會像無頭蒼蠅一樣亂找 Bug,而是能精準切入:到底是網路斷了、憑證過期、後端當機,還是前端的 JS 寫爛了?
今天,我們就從一個系統管理兼全端開發者的視角,把這個「黑盒子」徹底打開。
🕵️♂️ 第一步:問路與查水表(DNS 解析)
當你輸入 https://my-awesome-site.com 時,瀏覽器其實是個大路痴,它只認得 IP 位址(例如 192.168.1.1),根本不認識這一長串英文字母。所以它必須去查號台問路,這個過程叫做 DNS 解析 (Domain Name System)。
- 先翻自己的口袋: 瀏覽器會先看自己的快取、再看作業系統的快取(例如 Windows 的
hosts檔)。 - 打給查號台: 如果都找不到,就會去問你設定的 DNS 伺服器(通常是你的電信業者,或是 Google 的
8.8.8.8)。 - 層層上報: DNS 伺服器會一路從根節點往下問,直到找到這串網址對應的 IP 位址,然後把結果交給瀏覽器。
💡 維運工程師的血淚: 有時候你剛買好網域、設定好 IP,客戶卻抱怨連不上。這通常不是你 Code 寫錯,而是 DNS 紀錄在全球生效(TTL)需要時間。這時候我們通常只會無奈地說一句:「DNS 還沒更新完啦,等一下好嗎!」
🤝 第二步:打招呼與確認身分(TCP 三方交握與 TLS)
拿到 IP 位址後,瀏覽器準備要跟那台遠端的伺服器連線了。但在傳輸資料前,雙方必須先建立一條可靠的通道,這就是大名鼎鼎的 TCP 三方交握 (3-Way Handshake)。
- 瀏覽器: 「哈囉伺服器,你在嗎?我想建立連線。」 (SYN)
- 伺服器: 「我在喔!我收到你的請求了,那你準備好了嗎?」 (SYN-ACK)
- 瀏覽器: 「準備好了,我們開始吧!」 (ACK)
除了 TCP,現在的網址都是 https,所以還會多一道 TLS 握手的加密手續,雙方會交換憑證、協商加密算法,確保接下來傳遞的密碼跟資料不會被駭客看光光。
💡 維運工程師的血淚: 如果在這個階段卡住,瀏覽器通常會噴出
ERR_CONNECTION_TIMED_OUT。有八成的機率是伺服器根本沒開機、防火牆擋住了 Port 443,或是 SSL 憑證忘記去 Let’s Encrypt 更新導致過期被瀏覽器擋下。
✉️ 第三步:點餐與送單(發送 HTTP 請求)
連線建立且加密完畢後,瀏覽器終於可以發送真正的 HTTP GET 請求了。這就像是在餐廳點餐,瀏覽器會把一份寫滿需求的「點菜單」(Request Headers)送過去:
GET / HTTP/1.1
Host: my-awesome-site.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)...
Accept: text/html,application/xhtml+xml...
這張單子告訴伺服器:「我要首頁的 HTML 檔案,而且我是用 Windows 的 Chrome 瀏覽器喔。」
🍳 第四步:廚房大亂鬥(後端伺服器處理)
這時候,封包終於抵達了我們心愛的伺服器。
- 大門保全 (Reverse Proxy): 請求通常會先撞上 Nginx 或 Apache 這種反向代理伺服器。Nginx 會檢查一下規則,如果沒問題,就把請求轉交給背後的應用程式。
- 大廚上菜 (Backend App): 請求來到了我們寫的 FastAPI、Node.js 或是 C# 程式裡。
- 調閱資料 (Database): 後端程式發現這個頁面需要去資料庫撈資料(例如去 PostgreSQL 下一段 SQL 查詢)。
- 打包回應 (Response): 資料撈完、HTML 渲染好,或是 JSON 組裝完畢後,後端會把這些東西打包,貼上一張
200 OK的標籤,沿著原路送回給瀏覽器。
💡 維運工程師的血淚: 如果在這個階段等了老半天,最後噴出
502 Bad Gateway或500 Internal Server Error,代表廚房燒起來了!可能是資料庫的 SQL 寫太爛導致 CPU 飆到 100%、程式有 Bug 噴 Exception,或是後端服務根本就掛掉沒啟動(這時候就可以打開我們用 ECharts 寫的監控儀表板,看看是不是 RAM 被吃光了)。
🎨 第五步:擺盤與上菜(瀏覽器解析與渲染)
最後,瀏覽器收到了伺服器寄來的 HTML 檔案,準備把這些冷冰冰的原始碼變成漂亮的網頁。這個渲染過程(Rendering Pipeline)也是一門極其複雜的藝術:
- 構建 DOM 樹: 瀏覽器一行一行讀取 HTML,把它轉成一棵 DOM 樹(Document Object Model)。
- 構建 CSSOM 樹: 遇到
<style>或外部的 CSS 檔案,就去下載並解析成 CSSOM 樹。 - 生成 Render Tree: 把 DOM 和 CSSOM 結合起來,計算出畫面上到底有哪些元素是「看得見」的。
- 排版 (Layout): 計算每個元素在螢幕上的確切座標與大小。
- 繪製 (Paint): 拿起畫筆,把文字、顏色、陰影畫到螢幕的像素上。
如果 HTML 裡面有 <script> 載入 JavaScript(像是 Vue.js 或我們寫的 ECharts 邏輯),瀏覽器還必須停下腳步去執行 JS,這也是為什麼我們通常會把載入巨大 JS 檔案的語法放在 HTML 的最底部,避免「阻塞渲染」導致白畫面太久。
🍻 總結:當工程師不再「通靈」
下次網址列按下 Enter 後,如果有哪裡出錯了,你可以試著在腦海裡跑一遍這個流程:
- 連不上?先
ping一下看是不是 DNS 找不到人。 - 憑證警告?那是 TLS 階段出問題。
- 狂轉圈圈噴
502?去檢查 Nginx 或是 後端伺服器 的 Log。 - 畫面出來了但排版全爛?恭喜,那是 CSS/DOM 的前端鍋。
把原理搞懂,除錯就不再是靠運氣「通靈」。這不僅是面試必考題,更是支撐我們每天解決千奇百怪 Bug 的最強底氣!
