綜合演練 — 從案例解讀 HTTP 的對話
對模擬實務故障調查的 8 個案例,套用「請求了什麼・結果如何・條件與補充」的 3 點組合閱讀法,橫跨運用全部 6 章的知識。
收尾的 8 題 — 把 3 點組合套用到案例上
最終章是綜合演練。對模擬實務場景的 8 個案例,橫跨全部 6 章的知識來回答。迷惘時,回到本課程的口訣 — 請求了什麼?結果如何?條件與補充是什麼?
| 卡住的話 | 回去的章 |
|---|---|
| 訊息的骨架・無狀態 | 第 1 章 |
| 方法的使用區分・安全與冪等・重試 | 第 2 章 |
| 狀態碼的分類與切分 | 第 3 章 |
| Host・Content-Type・Cookie 等標頭 | 第 4 章 |
| max-age・ETag・304・no-store | 第 5 章 |
| curl 與 Network 分頁的觀察步驟 | 第 6 章 |
案例調查的型。從症狀出發,依請求行(請求了什麼)→ 狀態碼(結果如何)→ 標頭(條件與補充)的順序閱讀,就能縮小原因所在的一側(用戶端側 / 轉送 / 伺服器側 / 快取)。
案例 7-1 — 重新導向與表單的問題
第 2〜3 章與第 6 章的範圍。解讀轉送的連鎖與 POST 的重送。
Q1. 案例:打開 https://example.com/mypage,瀏覽器顯示「重新導向次數過多」的錯誤。用 curl -v https://example.com/mypage 觀察,發現它以 302 轉送到 Location: /login,而 /login 也以 302 轉送到 Location: /mypage。對所發生之事的正確說明是哪一個?
追蹤 Location 的去向,可以看到 /mypage → /login → /mypage 的循環。典型的原因是登入判定的條件(Cookie 的有無等)在 2 個頁面間互相矛盾,彼此把對方當作轉送目的地。瀏覽器在一定次數後會中斷並顯示這個錯誤。若是 503,Status 就會那樣顯示;DNS 壞了的話根本連不上。curl 是把迴圈一段一段誠實呈現出來的那一方。
Q2. 案例:有使用者回報「在訂購完成頁面重新載入,出現表單重送的確認,繼續之後訂單變成兩筆」。伺服器端的定番對策是哪一個?
把對 POST 的 200 回應直接顯示出來,重新載入就等於重新執行 POST(POST 不冪等,可能造成雙重訂購 — 第 2 章)。POST/Redirect/GET 是處理後回傳重新導向、讓完成頁面以 GET 顯示的型;即使被重新載入,重複的也只是安全的 GET。no-store 解決不了重送問題,把訂購改成 GET 更是「用安全的方法改變狀態」的反向惡手。
Q3. 案例:圖片檔的回應標頭設定了 Cache-Control: max-age=604800。這份快取能保持 fresh 的期間是幾天?
604800 ÷ 86400(1 天的秒數)= 7 天。正是第 5 章常見值的換算。「可以快取 1 週」的設定在靜態檔案很常見,看到 604800 的瞬間能讀出 7 天,設定審查就會變快。
案例 7-2 — 沒反映・變亂碼・看不到
第 3〜6 章的範圍。切分快取・權限・字元編碼。
Q4. 案例:修改了 CSS 也反映到伺服器上了,自己的瀏覽器卻仍顯示舊的設計。看 Network 分頁,那個 CSS 那一行的 Size 欄顯示著 (disk cache)。原因與對策的組合,最合適的是哪一個?
(disk cache) 是「請求沒有送到伺服器」的決定性標記(第 5〜6 章)。伺服器修得再多,fresh 期間瀏覽器也不會來看。手邊的確認用 Disable cache 就夠了,但所有使用者的快取是消不掉的,所以永久對策的定番是像 style.v2.css 這樣改變 URL 本身、讓它被當成「另一個資源」取得的設計。若是上傳失敗,Size 欄應該會顯示一般的傳輸量。
Q5. 案例:在會員制網站,已登入的使用者回報「昨天還看得到的資料頁面,今天開始看不到了」。Network 分頁中對該頁面的 GET 回傳 403。從這個觀察能說的、最合適的是哪一個?
403 是「知道你是誰,但沒有權限」(第 3 章)。若是刪除會是 404,伺服器掛了會是 5xx 或連線錯誤;回傳 403 的當下,伺服器就活著、請求也送達了。配合「昨天還看得到」,就能把調查方向縮小到資料的公開範圍、會員種類或權限設定被變更的可能性。一個狀態碼,就能讓該懷疑的位置改變這麼多。
Q6. 案例:改版後的 https://example.com 頁面上,日文化成了「è±�å�」這樣的符號串。用 curl -I 確認,回傳的是 Content-Type: text/html; charset=ISO-8859-1,而 HTML 檔案本身是以 UTF-8 儲存的。合適的對策是哪一個?
實體是 UTF-8、標籤是 ISO-8859-1 — 正是第 4 章讀過的「標籤與內容物不一致」。瀏覽器相信宣告、用錯誤的字元編碼解讀位元組序列,所以變成亂碼。該修的是伺服器的 charset 宣告;要求使用者每次改設定,或把本文改成英文・圖片的方案,連迴避原因的做法都算不上。修好標頭,所有人的顯示就一次修好。
案例 7-3 — 故障的切分與重試的判斷
第 2〜3 章的總結。以 5xx 的切分與基於冪等性的重試判斷為課程收尾。
Q7. 案例:整個網站突然出錯,任何 URL 都回傳 502 Bad Gateway。構成是「反向代理 + 後面的應用程式伺服器」的 2 段式。最先調查的位置,最合適的是哪一個?
502 是「中繼者活著,但無法從後面取得正常回應」(第 3 章)。502 這個 HTTP 回應能回來,本身就是能到達代理的證據。所以第一步是應用程式伺服器的存活狀況與記錄檔。若原因是瀏覽器設定或 DNS 合約,根本不會收到 502 這種形式的回覆。3 位數字,連 2 段構成中是哪一側都告訴你了。
Q8. 案例:庫存管理系統中有 2 個請求逾時了。(A) PUT /items/42(把商品 42 的資訊置換成這份內容)與 (B) POST /orders(建立新的進貨單)。可以機械式地立刻重送的是哪一個?
課程的收尾是第 2 章的實務感覺。逾時包含「已被處理、只有回覆遺失」的可能性。PUT 是置換成相同內容,就算被處理了 2 次最終狀態也相同 — 可以放心重送。POST 被處理 2 次就是 2 筆進貨單;沒有確認或防重複機制的重送就是事故。「更新的重試,先確認冪等性」— 請把這句話帶回家。
課程的最後 — 隨身帶著往返書信的讀法
辛苦了。在本課程中背下來的項目其實非常少。取而代之希望你帶回家的,是在任何輸出面前都通用的閱讀之型。
- 請求了什麼 — 請求行的方法與路徑。那個請託是安全的嗎、冪等的嗎
- 結果如何 — 狀態碼從百位數讀起。先知道是誰的問題
- 條件與補充是什麼 — Content-Type 與內容物一致嗎。Cache-Control 約定了什麼。Cookie 有附上嗎
開發者工具的 Network 分頁也好、curl -v 的輸出也好、明天起遇到的任何 HTTP 記錄也好,都一定能從這 3 點開始讀。不被壓倒,從熟悉的 3 點讀起 — 這就是你在本課程練成的能力。