ByteScope

HTTP 狀態碼對照

每個 HTTP 狀態碼是什麼意思,以及前端、後端、使用者各自該怎麼處理。

檔案不會離開你的瀏覽器 — 全部在本機處理。

從你收到的那個代碼開始查。每一頁都把「規格說了什麼」和「你實際上要做什麼」分開寫,而且前端、後端、還有只是想把網頁打開的人,會被當成三個不同的問題來回答。

依類別篩選
代碼名稱類別代表什麼
301Moved Permanently3xx舊網址退休了,接手的是 `Location` 裡的那一個——而 301 是少數幾種伺服器沒交代、快取也可以自己存起來的回應,所以送錯的 301 是最難收回來的一種轉址。
302Found3xx一次暫時的繞路:資源還是屬於你要的那個網址,只是現在伺服器想從別的地方把它送出來——而你的瀏覽器會直接繞過去,完全不會讓你的程式碼看到這一跳。
304Not Modified3xx你手上那份還是好的:你在請求裡帶了驗證器,伺服器拿去跟自己那份比對,一樣,於是它刻意只回標頭、不回內容。
400Bad Request4xx伺服器根本不願意去解讀這個請求——請求行、某個標頭、訊息框架或 body 裡有東西格式錯了或太大——通常這代表你的應用程式碼一行都沒跑到。
401Unauthorized4xx這個請求沒有帶上可用的認證憑證——原因片語寫的是 Unauthorized,但它描述的狀況其實是「沒認證」,而且伺服器有義務用一個標頭告訴你什麼樣的憑證才行。
403Forbidden4xx伺服器完全看懂了這個請求,而且拒絕執行它——跟 401 不一樣的是,它沒有義務給你任何一個標頭去說明怎樣才行得通。
404Not Found4xx伺服器看懂了你的請求,只是那條路徑上沒有東西可以給你。在現在的架構裡,這比較常是路由或部署漏掉了一步,而不是誰貼了一條死連結。
405Method Not Allowed4xx路徑在,方法伺服器也認得——它只是不接受你在這裡用這個方法,而且它有義務把它願意收的方法清單交給你。
429Too Many Requests4xx某個限流器認定你問得太頻繁了——這是一句政策上的宣告,不是協定上的,所以兩個都回 429 的服務,數的可能是完全不同的東西。
500Internal Server Error5xx應用程式自己跑起來了,撞到一個它沒預期的東西,然後放棄——所以跟 502、504 不一樣,某個地方一定有一份 stack trace,而整件事的工作就是找出它在哪一份紀錄裡。
502Bad Gateway5xx應用程式前面那台代理替它回了話,因為應用程式自己的回應沒來、中途斷掉,或根本不是合法的 HTTP。
503Service Unavailable5xx有某個東西決定現在不服務你,而且是刻意的——維護頁、限流器,或者一台手上沒有任何健康後端可以轉的負載平衡器——這讓 503 成為唯一附帶到期日的 5xx。
504Gateway Timeout5xx代理等某台 upstream 等到沒耐心了,於是替它回話——所以真正指認兇手的不是狀態碼,而是耗掉的時間,那永遠是某個人設定的逾時。
521Web Server Is Down非標準5xxCloudflare 自己的代碼、不是 IETF 的,指的是整個 5xx 範圍裡最窄的一種失敗:你的來源機主動拒絕了 Cloudflare 的 TCP 連線,所以沒有東西慢、也沒有東西送錯地方——是有東西說了不。
524A Timeout Occurred非標準5xxCloudflare 自己的代碼,用在一個一路進得去、然後就沒聲音的請求上:連線成功了、來源機收到了,而 125 秒之後還是沒有任何 HTTP 回應可以送回來。

關於這個工具

為了「有人丟三個數字給你」的那一刻而寫 幾乎沒有人是出於好奇才去查狀態碼的。會查,通常是因為剛部署完一半的請求就變紅了、因為客戶回報了一個沒人重現得出來的錯誤,或者因為監控警報只丟了三個數字過來。所以這裡每一頁都先講這個代碼告訴你「故障在哪一段」,然後才講規格怎麼寫。定義是比較短的那一半;決定要去看路由、看代理,還是看上游,才是會吃掉一個下午的那一半。

三種讀者,就有三個答案 前端工程師看到的 404,通常是「用點的可以開、一重新整理就壞」的那種路由。同一個 404 落到後端工程師眼裡,通常是應用程式看到路徑之前,被前面加上或剝掉的那一段代理前綴。而在使用者眼中,它就是一條搬走了的連結。這是三個不同的問題、三種不同的修法,把它們揉成同一段的頁面,三個人都幫不上——所以這裡每個代碼都分開回答,而且當某一種讀者最誠實的答案是「你什麼都不用做」時,就直接寫出來。

是標準、是廠商自訂,還是只是習慣 RFC 9110 定義了那些照規格實作的用戶端與伺服器解讀一致的狀態碼;有幾個常用的住在自己的文件裡,429 在 RFC 6585、308 在 RFC 7538。而你在正式環境會遇到的代碼裡,有不少兩邊都不屬於:499 來自 nginx 的原始碼,520 到 526 一整段則是 Cloudflare 的,它們被發明出來,就是為了不讓邊緣節點和來源機之間的失敗被籠統地報成 502。每一頁都會寫清楚自己屬於哪一種,因為這決定了哪一份文件才是權威——而這個網站本身就跑在 Cloudflare 上,所以 52x 那幾頁是站在跟你同一邊寫的。

常見問題

HTTP 狀態碼的 1xx 到 5xx 各代表什麼?

第一個數字就是整個分類。1xx 是資訊性的,在應用程式的程式碼裡很少浮上來;2xx 代表請求成功;3xx 代表還需要進一步動作,通常是跟著轉址走;4xx 代表請求本身有問題;5xx 代表伺服器在處理一個看起來合法的請求時自己出了狀況。RFC 9110 還規定,用戶端遇到不認得的代碼時必須當成它那一類的 x00 來處理,所以看到沒見過的 599,照 500 處理是安全的。

怎麼看一個網頁實際回的是什麼狀態碼?

在瀏覽器裡,打開開發者工具的網路面板,讀那個請求本身的 Status 欄,不要讀它連帶載入的那些檔案。在終端機裡,curl -sS -o /dev/null -w '%{http_code}\n' https://example.com/page 只會印出數字,再加上 -D - 就會連回應標頭一起印。兩邊不一致時要相信終端機那個:擴充功能、Service Worker,或一份被快取的回應,都能改掉瀏覽器給你看的東西。

4xx 是我的錯、5xx 是對方的錯,這樣講對嗎?

這是當初分類的用意,但它是經驗法則,不是保證。設定錯的伺服器一樣會吐出一堆 4xx——被代理弄壞路徑而回的 404、被一條沒人打算套用的規則擋下的 403;反過來,一個要求過頭的請求也一樣會觸發 5xx。用這個分類決定先看哪一邊就好,不要拿它來決定誰該負責。

這些代碼裡哪些其實不是標準?

418 出自愚人節的 RFC,是個玩笑,但真的還有伺服器在回它。499 根本沒有在 IANA 登記過,它來自 nginx,意思是「伺服器還沒回答,用戶端就把連線關掉了」,所以它出現在存取紀錄裡,不會出現在瀏覽器上。520 到 526 是 Cloudflare 自己的,只有 Cloudflare 的文件在定義它。至於 429,雖然感覺像是後來補的,它是 RFC 6585 的正式標準,308 也是,出自 RFC 7538。

狀態碼會影響 SEO 嗎?

有幾個影響很大。301 會把排名訊號帶到新的網址,302 則是告訴爬蟲這次搬家是暫時的、舊的請留著,所以永久搬遷卻用 302,等於默默付出代價。404 會讓爬蟲過一陣子再回來看,410 則是直接告訴索引器這個資源結束了。最糟的是 soft 404——用 200 回一頁錯誤訊息——因為搜尋引擎會把那段道歉文字當成內容收進索引。