從瀏覽器看見網路模型:你寫的程式,怎麼跟後端溝通資料?
更新日期: 2025 年 4 月 7 日
本文為 網路模型基礎 系列文:
你可能每天都在寫 fetch()
、用 GraphQL 查資料、打 API、開 DevTools 查錯……但你是否想過:
- 這些資料是怎麼從你程式送出去的?
- 每一次送出請求,背後經過了哪些網路流程?
- 你在 Network 工具看到的資訊,對應的是網路模型的哪一層?
這篇文章,會從實際工作中的觀察經驗出發,一步步帶你了解:
- 怎麼用瀏覽器「看見」網路發生了什麼事
- 程式和網路模型之間的對應關係
- 如何根據 payload 推理後端的資料結構
一個簡單的例子:從前端送出一筆 GraphQL 請求
假設你在前端寫了一段程式碼,用來送出 GraphQL 查詢:
fetch("https://api.example.com/graphql", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
query: `
query {
user(id: "123") {
name
email
}
}
`
})
})
你點開瀏覽器的 DevTools,切換到 Network 面板,就會看到:
- 一個 POST 請求發送到
/graphql
- payload 中包含你寫的 GraphQL 查詢語法
- response 中回來了資料
{ "data": { "user": { ... }}}
這整個流程,就是你「親眼看到網路模型運作」的最佳切入點!
對照網路模型:你在用的到底是哪幾層?
讓我們從這個 fetch()
例子,一層層對照網路模型的運作:
應用層(Application Layer):你程式在說話的地方
你寫下 fetch()
,實際就是啟動了一個 HTTP 請求,屬於應用層的行為。這層的角色是:
- 讓人類可讀的資料與網路溝通
- 包含常見協定如:HTTP、HTTPS、DNS、Email、FTP
在這層你看到的是:
- Request URL、Method(GET / POST)
- Header:Content-Type, Authorization…
- Payload:GraphQL 查詢語法
- Response:回傳 JSON 資料
✅ 你使用 Network 工具查看這些,就是在觀察應用層!
傳輸層(Transport Layer):資料要怎麼傳?
應用層的資料會往下交給傳輸層來處理「傳送細節」:
- 通常使用 TCP 協定(會幫你建立連線、確認資料有送到)
- 負責資料切分、順序排列、錯誤重傳等機制
你在 DevTools 的「Timing」區塊會看到:
- TCP Handshake 時間
- 請求花費的傳輸時間(等效反映 TCP 層的運作)
✅ 雖然你不會直接寫 TCP,但它默默幫你處理一切!
網路層(Network Layer):找出資料該走的路
傳輸層資料會再往下送給網路層:
- 使用 IP 協定決定資料要送去哪一台伺服器
- 使用 ICMP 協定幫你診斷(如
ping
)
雖然 DevTools 看不到這一層太細節的東西,但你知道:
- 請求會查 DNS,把網址轉成 IP
- IP 資訊會隨著封包送出去,幫助資料找到目的地
資料連結層 & 實體層:資料真的在「走」
最底層是實際發送資料的硬體層:
- Ethernet、Wi-Fi、光纖
- MAC 位址、Switch 轉送
- 電線、電磁波等實體媒介
這些通常在網卡層級才會看得到,可以用專業工具(如 Wireshark)來觀察封包在這層的資訊。
DevTools 操作教學:用 Network 面板看見你的請求「走過哪些層」
瀏覽器 DevTools 是開發者的放大鏡,它不只能查 CSS 和 Console log,Network 面板更是你理解網路模型與 API 溝通機制的最佳入口。
基本操作教學:如何觀察一個網路請求的「五官」
1. 開啟 DevTools
- 在 Chrome 中按
F12
,或是右鍵選擇「檢查」 - 切換到上方的 Network 分頁
- 建議勾選「Preserve log」避免頁面重整時請求消失
2. 發出請求
- 重新整理頁面
- 或執行一段會觸發 fetch / axios / XMLHttpRequest 的操作(例如按下送出按鈕)
3. 點選一個請求,分別觀察以下幾個區塊:
Headers:看出協定與 API 溝通方式(屬於應用層)
- Request URL:你發出請求的網址(包含 domain 與路徑)
- Request Method:GET、POST、PUT、DELETE…
- Status Code:200 OK、404 Not Found、500 Internal Server Error
- Request Headers:如 Content-Type、Authorization、Cookie…
- Response Headers:如 Content-Type、Cache-Control、Set-Cookie
✅ 可用來:
- 確認你發的是哪種請求(GET or POST)
- 檢查是否有帶上認證 Token
- 理解後端的資料格式與快取策略
Payload:觀察實際送出的資料(你寫的程式 → 網路請求)
只對 POST、PUT 類型的請求顯示 payload!
- 如果是 REST API,會看到送出的 JSON 資料
- 如果是 GraphQL,則會看到:
query
: 查詢語句本身variables
: 傳入的參數operationName
:(可選)API 操作名稱
✅ 可用來:
- 對照你程式中寫的請求(是否有拼錯欄位、漏帶資料)
- 看出 GraphQL 查了哪些資料 → 推理後端的資料表結構 例如:
查詢user(id: "123") { name, email }
→ 推測後端有一張user
資料表,欄位有name
與email
Payload 頁籤跟封包的 Payload 有關嗎?
DevTools 中看到的「Payload」 並不完全等於 網路封包中的 Payload,但它們有關係。
它是「應用層資料」的一部分,會被包裝進封包的 payload 區域裡,但在 DevTools 裡你看到的是比較高階、易讀的形式,也就是「你送給 HTTP 的資料內容」。
🧠 詳解:兩個「Payload」的對照與差異
類別 | DevTools 的 Payload | 網路封包中的 Payload |
---|---|---|
層級 | 應用層(HTTP 層) | 傳輸層以下(TCP/IP 封包) |
內容 | JSON、GraphQL 查詢、表單欄位等 | 封包裡的資料部分(可能是 HTTP 請求、也可能是別的協定資料) |
可讀性 | 已經經過解析、格式化 | 原始位元組序列,需要工具解析(如 Wireshark) |
工具 | 瀏覽器 DevTools | Wireshark、tcpdump |
✅ 結論:兩者的關係是這樣的
當你在前端寫這段程式碼:
fetch("https://api.example.com", {
method: "POST",
body: JSON.stringify({ name: "Alice" })
})
整個流程會像這樣:
- 你寫的 JSON
{ name: "Alice" }
是「應用層資料」 - 瀏覽器包成 HTTP 請求 → 放進 HTTP 的 message body → 這就是 DevTools 裡看到的 Payload
- HTTP 請求再被包進 TCP 封包 → 這一層的 payload 是整個 HTTP 訊息(包含你剛剛的 JSON)
- 再被包進 IP 封包 → Ethernet 封包 → 最後送出去
所以你看到的 DevTools Payload,其實就是「應用層資料會放進網路封包中 payload 區域的一部分」,但這是更上層、更容易讀懂的格式。
Response:分析伺服器回傳的資料內容
- 通常是 JSON 或 HTML 格式
- 可以看到資料格式、結構、回傳值
✅ 可用來:
- 確認是否收到資料(非空回傳)
- 檢查錯誤訊息(如權限錯誤、資料不存在)
- 比對預期回傳的結構與實際內容
Timing:這其實就是你「看到傳輸層和網路層」的地方!
點選 Timing 區塊,你會看到一條時間軸,包含:
區段 | 意義 | 對應層級 |
---|---|---|
DNS Lookup | 查詢網域名稱對應的 IP | 網路層 |
Initial Connection | 建立 TCP 連線 | 傳輸層 |
SSL | HTTPS 加密握手 | 傳輸層(含 TLS) |
Request Sent | 資料開始發送 | 傳輸層 |
Waiting (TTFB) | 等待伺服器回應 | 傳輸層 / 應用層 |
Content Download | 資料接收完畢 | 傳輸層 |
✅ 可用來:
- 看出慢在哪一段(DNS 很久?還是伺服器太慢?)
- 分析效能瓶頸,排查 API 回應不穩或延遲問題
進階用法:讓你像工程師一樣用 Network 面板思考
1. 從 Payload 推 API 設計邏輯
query { user { name } }
→ 預測有一個user
查詢函式- 看變數的型別與深度推測資料庫結構
2. 從欄位名猜資料表
productList { id, name, price }
→ 很可能對應products
資料表order.items[].productId
→ 推測有orders
與order_items
關聯表
3. 從程式比對實際請求
- 程式寫的
fetch()
是否正確轉換成 payload - headers 有沒有正確帶入 Token 或自訂欄位
- 回傳資料是否如預期解析 JSON 後結構正確
🧠 為什麼這麼做很重要?
✅ 更快 Debug:錯在哪一層馬上知道
- 403 → Token 錯誤(Header 問題)
- 無資料 → Payload 送錯欄位(應用層問題)
- 請求掛住 → TCP 沒建立(傳輸層問題)
✅ 更懂 API 與後端資料邏輯
- 你不再只是「呼叫 API」,而是能理解「這個 API 背後應該查哪一張表」
- 更有能力與後端或資安工程師溝通
✅ 能說出「同一層語言」
- 不再只說「這 API 壞掉了」,而是能說: 「這個 POST 請求 payload 裡 userId 是空的,導致後端回傳 400,可能在前端組合資料時漏了欄位。」
- 跟其他工程師合作時,這種觀察力就是你的加分技能
最後小結:程式設計,也是一場網路旅行
每一個 fetch
、每一段 GraphQL、每一次 payload 傳輸,都是你與網路模型的互動。
模型層級 | 開發者可見內容 |
---|---|
應用層 | fetch(), GraphQL, JSON payload |
傳輸層 | TCP 時間, Response 速度 |
網路層 | DNS 解析, IP 尋址(工具輔助觀察) |
資料連結層 | MAC 位址, 封包傳輸(需用 Wireshark) |
實體層 | 電線、Wi-Fi、硬體設備 |
從你寫程式,到封包送出,再到後端處理,這段過程就是開發者必經的網路旅程。