小村軟體有限公司
第 3 章

HTTP 狀態碼 — 用 3 位數讀出結果

狀態碼先用百位數分成 5 類,再讀後 2 位。切分成功的 200/201/204、重新導向的 301/302/308、用戶端問題的 401/403/404、伺服器端故障的 500/502/503。

為了在被問到「404 和 403 差在哪?」時不語塞

錯誤畫面的截圖被傳過來,附一句「這能修嗎」。是 404、403 還是 503,原因與修法完全不同,但光看數字的長相每個都一樣 — 狀態碼想用背的,有幾十個,多數人就此挫敗。

不需要背。與狀態碼的正確相處方式是先用百位數分成 5 類,再只讀常見的後 2 位。3 點組合的第 2 點「結果如何」,首先由百位數來回答。

1xx — 處理進行中
途中經過的通知。日常開發中很少見到
2xx — 成功了
請託被受理、被處理了
3xx — 請到別的地方
答案在別的 URL。轉送目的地寫在 Location 標頭
4xx — 你的請求方式有問題
用戶端的問題。不存在的路徑、認證不足、權限不足等
5xx — 我方的處理出了差錯
伺服器端的故障。即使請求正確也會發生

調查的第一步由這個分類決定。4xx 就先懷疑請求側(URL・認證・送出的內容),5xx 就懷疑伺服器側(應用程式的記錄檔・後段的服務)。光是不搞反這個方向,原因調查就完成了一半。

把 HTTP 狀態碼用百位數分成 1xx 到 5xx 的 5 類,標出各自的意義與代表代碼的圖表

用百位數分成 5 類,在各類之中只讀分「常見的幾個」— 這就是狀態碼的地圖。箭頭所指的代表代碼,就是本章要處理的全部。

2xx — 成功也有使用區分

成功不是只有 200。把常見的 3 個排在一起。

200 OK
成功的通用形。把被請求的東西(HTML・JSON 等)放進內文回傳
201 Created
成功,並且建立了新資源。POST 建立成功的定番,多半會把新建立資源的 URL 附在 Location 標頭
204 No Content
成功了,但沒有本文可回。最適合刪除或更新的成功報告

當你成為做 API 的那一方,能不能區分使用這 3 個,會改變回覆的可讀性。不只說「成功了」,還用 3 位數傳達「成功了,然後什麼變成了怎樣」— 這就是 2xx 的活用。

練習 3-1 — 用百位數分類

先用百位數做大分類,再讀出成功系後 2 位的差別。

Q1. 狀態碼百位數的正確讀法是哪一個?

Q2.POST /orders 成功建立了新訂單時,意義上最貼切的狀態碼是哪一個?

Q3. DELETE /orders/7 成功了,伺服器沒有特別要回傳的本文。此時自然的狀態碼是哪一個?

3xx — 「請到別的地方」的使用區分

3xx 的回應是一張引導單:「答案不在這裡。請前往寫在 Location 標頭的 URL」。瀏覽器收到後會自動向轉送目的地重新發出請求。常見的是以下 3 個,差別可以用 2 個軸來讀。

301 Moved Permanently — 永久
「今後永遠在那邊」。瀏覽器可以快取這個轉送,搜尋引擎會把新 URL 重新登錄為正牌(SEO 的評價會被繼承)。適用於 http 到 https 的搬遷等
302 Found — 暫時
「只有現在在那邊」。不會被快取,登錄也不會被改寫。適用於維護中的暫時避難等
308 Permanent Redirect — 永久 + 保留方法
和 301 一樣永久,但保證POST 以 POST 原樣轉送。(暫時 + 保留方法是 307)

第 2 軸「保留方法」是歷史因素的產物。在 301/302,為了與舊實作相容,允許 POST 被改寫成 GET 再轉送。若是 HTML 頁面的搬遷幾乎沒有實害,但 API 的 POST 變身成 GET,請託本身就變了。於是後來準備了明確表示「不改變方法」的 307/308。永久或暫時 × 是否保留方法 — 用這 2 個軸就能整理這 4 個代碼。

4xx 與 5xx — 說中是誰的問題

在 4xx 之中,看起來相似的 3 兄弟的區分很重要。

401 Unauthorized
還沒有通過認證。請先報上名來」。與名字相反,是未認證的意思。登入或附上認證資訊就可能通過
403 Forbidden
「知道你是誰,但沒有權限」。即使正確登入,也不被允許做那個操作
404 Not Found
「那個路徑找不到資源」。URL 打錯、已刪除、尚未公開等

在 5xx 之中,能切分這 3 個,故障應對的第一步就會不同。

500 Internal Server Error
應用程式內部的預期外錯誤。先看的是應用程式的記錄檔
502 Bad Gateway
前面的中繼者(反向代理等)無法從後面的伺服器取得正常回應。要懷疑的是中繼者的後面那一側
503 Service Unavailable
因過載或維護而暫時無法回應。不是「壞了」,而是「現在不行」的表述

能讀懂 502 之所以強大,是因為現代的 Web 伺服器多為「中繼者(nginx 等)+ 後面的應用程式」的 2 段構成。502 連中繼者還活著、倒下的是後面這件事都告訴你了。一個數字,就把要調查的位置縮小了一段。

練習 3-2 — 切分重新導向與錯誤

3xx 的使用區分,以及 4xx・5xx 內部的切分。實務調查的第一步會因此不同。

Q4. 網站從 http://example.com 永久搬遷到 https://example.com。選擇 301 的正確理由是哪一個?

Q5. 308 Permanent Redirect 之所以另外準備、與 301 並存的正確理由是哪一個?

Q6. 已登入的一般使用者存取管理畫面 https://example.com/admin,被拒絕了。表示「不是頁面不存在,而是已通過認證但權限不足」的最貼切代碼是哪一個?

本章帶回家的重點

  • 狀態碼用百位數分 5 類 — 途中經過 / 成功 / 轉送 / 用戶端的問題 / 伺服器端的故障。調查的第一步在這裡決定
  • 成功的使用區分:200 通用 / 201 被建立了 / 204 成功但無本文
  • 重新導向是永久或暫時 × 是否保留方法的 2 軸 — 301・302・308(與 307)。永久會被快取,SEO 評價也會被繼承
  • 區分401 未認證 / 403 權限不足 / 404 不存在,以及500 應用程式內部 / 502 後面倒了 / 503 暫時不行

結果的讀法已經上手,下一章是 3 點組合的第 3 點 — 附在往返書信上的「條件與補充」,閱讀標頭。