The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

網頁開發人員應了解的 HTTP 狀態碼

分享到噗浪!

我想一般人對於 HTTP 狀態碼(Status Code) 多少會有些印象,例如 HTTP 200 代表網頁正常、404 代表找不到網頁。但似乎一般人大多不曾仔細研究所有 HTTP 狀態碼的定義,以及 HTTP 狀態碼到底對開發人員來說有何影響。

我承認,就算你完全不瞭解 HTTP Status Code 也可以開發出一個網站,若你寫的是 ASP.NET 也通常不會影響你的開發作業,因為 ASP.NET 已經包裝的很好了。

但是若網站架構越來越大,需要微調的時候,或是系統整合需要整合到更底層的網路作業時,若不瞭解這些代碼的意義 (或根本不知道有 HTTP 狀態碼這玩意),可能很容易就會遇到瓶頸,尤其是在除錯的時候更加明顯,我就曾經看過有人因為網頁收到 404 的錯誤訊息還一直在找程式哪裡出錯了,完全沒想到是自己網址打錯。

HTTP 狀態碼指的是從伺服器端回應(HTTP Response)的狀態,對於狀態的分類可區分三個層級,分別用三個數字表示,第一個數字為大類、第二個數字為中類、第三個數字為小類。完整的狀態碼定義可以參考 RFC 2616 Hypertext Transfer Protocol -- HTTP/1.110 Status Code Definitions 章節,裡面有完整且詳盡的說明。

不過在 IIS 中有不少微軟自訂的擴充狀態碼,格式類似 404.0 這樣,清楚的狀態碼對於除錯很有幫助。

HTTP 狀態碼大致分成 5 類 (粗體表示),完整的狀態碼概述如下:

  • 1xx - 參考資訊 (Informational)
    這些狀態碼代表主機先暫時回應用戶端一個狀態,所以在接收一般的回應之前,用戶端應準備接收一個或多個 1xx 的回應。我以前在寫 ASP 的時候比較有看到 IIS 使用到這些狀態碼回應,在 Apache 的環境我還未曾遇到過。
    • 100 - 繼續。
    • 101 - 切換通訊協定。
  • 2xx - 成功 (OK)
    這類的狀態碼表示伺服器成功接收到用戶端要求、理解用戶端要求、以及接受用戶端要求。
    • 200 - 確定。 用戶端要求成功。
    • 201 - 已建立。
    • 202 - 已接受。
    • 203 - 非授權資訊。
    • 204 - 無內容。
    • 205 - 重設內容。
    • 206 - 部分內容。
    • 207 - 多重狀態 (WebDAV) -- 這好像只有在 IIS 中才有,HTTP/1.1 並沒有定義這個狀態。這狀態會出現在可以包含多個不同回應代碼 (視子要求數量而定) 的 XML 訊息之前。
  • 3xx - 重新導向 (Redirection)
    用戶端瀏覽器必須採取更多動作才能完成要求。例如:瀏覽器可能必須重新發出 HTTP Request 要求伺服器上的不同頁面。
    • 301 - 要求的網頁已經永久改變網址。此狀態要求用戶端未來在連結此網址時應該導向至指定的 URI。
    • 302 - 物件已移動,並告知移動過去的網址。針對表單架構驗證,這通常表示為「物件已移動」。 要求的資源暫時存於不同的 URI 底下。 由於重新導向可能偶而改變,用戶端應繼續使用要求 URI 來執行未來的要求。 除非以 Cache-Control 或 Expires 標頭欄位表示,此回應才能夠快取。
      ASP.NET 預設的 Response.Redirect 方法,就是以 302 Found 做回應。
    • 303 - 通知 Client 連到另一個網址去查看上傳表單的結果(POST 變成 GET),當使用程式作網頁轉向時,會回應此訊息。
      在 ASP.NET 中要輸出 HTTP 303 轉向的程式碼如下:
      Response.StatusCode = 303;
      Response.RedirectLocation = "/PageB.aspx";
    • 304 - 未修改。用戶端要求該網頁時,其內容並沒有變更,應該回傳 304 告知網頁未修改。此時用戶端僅需要取得本地快取(Local Cache)的副本即可。
    • 305 - 要求的網頁必須透過 Server 指定的 proxy 才能觀看 ( 透過 Location 標頭 )
    • 306 - (未使用) 此代碼僅用來為了向前相容而已。
    • 307 - 暫時重新導向。要求的網頁只是「暫時」改變網址而已。
  • 4xx - 用戶端錯誤 (Client Error)
    這代表錯誤發生,且這錯誤的發生的原因跟「用戶端」有關。例如:用戶端可能連結到不存在的頁面、用戶端的權限不足、或可能未提供有效的驗證資訊(輸入的帳號、密碼錯誤)。下次看到 4xx 的回應千萬不要傻傻的一直查程式哪裡寫錯誤了(不過也有可能是程式造成的)。
    • 400 - 錯誤的要求。
    • 401 - 拒絕存取。 IIS 定義數個不同的 401 錯誤,以表示更詳細的錯誤原因。 這些特定的錯誤碼會顯示在瀏覽器中,但不會顯示在 IIS 記錄檔中:
      • 401.1 - 登入失敗。
      • 401.2 - 因為伺服器設定導致登入失敗。
      • 401.3 - 因為資源上的 ACL 而沒有授權。
      • 401.4 - 篩選授權失敗。
      • 401.5 - ISAPI/CGI 應用程式授權失敗。
      • 401.7 - Web 伺服器上的 URL 授權原則拒絕存取。 這是 IIS 6.0 專用的錯誤碼。
    • 403 - 禁止使用。 IIS 定義數個不同的 403 錯誤,以表示更詳細的錯誤原因:
      • 403.1 - 禁止執行存取。
      • 403.2 - 禁止讀取存取。
      • 403.3 - 禁止寫入存取。
      • 403.4 - 需要 SSL。
      • 403.5 - 需要 SSL 128。
      • 403.6 - IP 位址遭拒。
      • 403.7 - 需要用戶端憑證。
      • 403.8 - 網站存取遭拒。
      • 403.9 - 使用者過多。
      • 403.10 - 設定無效。
      • 403.11 - 密碼變更。
      • 403.12 - 對應程式拒絕存取。
      • 403.13 - 用戶端憑證已撤銷。
      • 403.14 - 目錄清單遭拒。
      • 403.15 - 超過用戶端存取授權數量。
      • 403.16 - 用戶端憑證不受信任或無效。
      • 403.17 - 用戶端憑證已經過期或尚未生效。
      • 403.18 - 無法在目前的應用程式集區中執行要求的 URL。 這是 IIS 6.0 專用的代碼。
      • 403.19 - 無法在這個應用程式集區中執行用戶端的 CGI。 這是 IIS 6.0 專用的代碼。
      • 403.20 - Passport 登入失敗。 這是 IIS 6.0 專用的錯誤碼。
    • 404 - 找不到。
      • 404.0 - (無) – 找不到檔案或目錄。
      • 404.1 - 無法在要求的連接埠上存取網站。
      • 404.2 - 網頁服務延伸鎖定原則阻止這個要求。
      • 404.3 - MIME 對應原則阻止這個要求。
    • 405 - 用來存取這個頁面的 HTTP 動詞不受允許 (方法不受允許)。
    • 406 - 用戶端瀏覽器不接受要求頁面的 MIME 類型。
    • 407 - 需要 Proxy 驗證。
    • 412 - 指定條件失敗。
    • 413 - 要求的實體太大。
    • 414 - 要求 URI 太長。
    • 415 - 不支援的媒體類型。
    • 416 - 無法滿足要求的範圍。
    • 417 - 執行失敗。
    • 423 - 鎖定錯誤。
  • 5xx - 伺服器錯誤 (Server Error)
    這代表錯誤發生,且這錯誤發生的原因跟「伺服器」有關。伺服器因為發生錯誤或例外狀況(Exception)而無法完成要求(Request)時,就會回應 5xx 的錯誤,且這肯定跟伺服器有關。
    • 500 - 內部伺服器錯誤。
      • 500.12 - 應用程式正忙於在 Web 伺服器上重新啟動。
      • 500.13 - Web 伺服器過於忙碌。
      • 500.15 - 不允許直接要求 Global.asa。
      • 500.16 – UNC 授權認證不正確。 這是 IIS 6.0 專用的錯誤碼。
      • 500.18 – 無法開啟 URL 授權存放區。 這是 IIS 6.0 專用的錯誤碼。
      • 500.19 - 此檔案的資料在 Metabase 中設定不當。
      • 500.100 - 內部的 ASP 錯誤。
    • 501 – 標頭值指定未實作的設定。
    • 502 - Web 伺服器在作為閘道或 Proxy 時收到無效的回應。
      • 502.1 - CGI 應用程式逾時。
      • 502.2 - CGI 應用程式中發生錯誤。
    • 503 - 服務無法使用。 這是 IIS 6.0 專用的錯誤碼。
    • 504 - 閘道逾時。
    • 505 - 不支援的 HTTP 版本。

至於詳細的狀態碼說明可參考以下相關連結:

評論 (15) -

  • Alex

    2009/1/20 上午 02:22:28 |

    207 - 多重狀態 (WebDay)<-----webdav

  • will

    2009/1/20 上午 03:25:19 |

    Thanks!  已修正

  • 熊~

    2009/9/23 下午 05:10:11 |

    請問500.100內部錯誤 這是指主機有問題還是asp程式有問題?

  • Will 保哥

    2009/9/23 下午 06:28:01 |

    熊~: 是 ASP 程式有問題,但問題也有可能是主機環境造成的。

  • 熊~

    2009/9/23 下午 06:49:00 |

    喔喔
    因為我在藍色小舖那邊找了一隻asp討論區用
    有時候就會突然變500.100
    所以就搞不懂到底是那程式有問題 還是主機漏了什麼

  • Will 保哥

    2009/9/23 下午 10:29:48 |

    你可以去藍色小舖那邊問。

  • wil

    2011/7/9 下午 04:48:25 |

    保哥您好,我想要請教一下
    我有支ASP.NET程式,正常情況下執行都沒問題,IIS LOG sc-status都是200
    但是如果我一直連續狂點refresh時(因客戶想看資料庫是否更新)
    IIS LOG sc-status會變成400 , sc-win32-status=64
    因您上面文章提到400是"錯誤的要求",
    想請問說, 程式是同一支也沒有傳參數, 為什麼會被IIS判斷是bad request呢?
    另外大量出現302,304會不會影響效能呢??有沒有預防的方式呀
    以上,thanks

  • Will 保哥

    2011/7/10 上午 01:26:24 |

    wil,

    會發生 400 Bad Request 的原因通常是 HTTP Request 的內容格式錯誤或不完整,你連續狂點時上一個要求被發送到一半就被你中斷了,所以是有可能引發 HTTP 400 的錯誤的。

    出現 304 是好的,代表你的網站內容有很多不需要下載。至於 302 是因為要轉向,看是不是你程式的行為導致。這兩個狀態都是正常的,你但有 HTTP Request 自然會影響效能(只有影響一點點而已),最好的方式還是將資料快取在用戶端,你連一個 Request 都看不到,這樣效能最好! Smile

  • Walter

    2011/7/15 上午 01:11:47 |

    Dear 保哥

    我的status Code只顯示500
    要怎麼確定他是500的哪一個阿

    而500是伺服器有問題
    是指iis的問題還是說,程式Server端的問題

    不知道有什麼辦法可以模擬這問題嗎
    不知道有辦法預防這樣的問題(statuscode500)嗎

    謝謝

  • Will 保哥

    2011/7/15 上午 01:21:49 |

    Walter: 這不是一個可以簡單解釋的問題,一般來說都是程式的問題,如果是 IIS 導致的問題通常都會有 500.xx 的編號。

    若要預防這種問題基本上就是程式寫好錯誤處理(Error Handling)的部分即可。

  • Walter

    2011/7/15 上午 01:33:24 |

    謝謝你,保哥

    因為現在發生了一個問題,程式都透過javascript呼叫WebService(C#),而呼叫時都有指定成功與失敗的Function
    WSAgent.WebServiceFun(Onsuccess, Onfail)

    但是似乎兩個Function都沒有進入就直接跳出一個視窗
    Sys.WebForms.PageRequestManagerServerErrorException: An unknown error occurred while processing the request on the server. The status code returned from the server was : 500

    而好死不死系統Log居然掛了,沒有任何紀錄檔可以看><
    感覺就算程式有Exception,應該也會跑到Onfail這個Function,但是目前看起來是沒有的

    不知道保哥是否可以指點方向,不然我目前完全沒有頭緒,
    雖然你已經說是程式的部分了,但一時也不知道該如何是好

    謝謝

  • Will 保哥

    2011/7/15 上午 03:24:35 |

    Walter: 你可以用 try/catch 的方式攔截錯誤,並且把錯誤訊息透過適當的方式回傳,你的 JavaScript 應該能抓到適當的訊息出來顯示。

  • Walter

    2011/7/18 下午 06:10:39 |

    謝謝你 保哥
    我會好好檢查一下的

  • winzen

    2013/8/28 下午 08:20:42 |

    你好,2009年時曾引用[HTTP 狀態碼]這篇文章在blog中當作工作時的參考,很久沒管blog了,發現有網友詢問哪一篇才是原版,避免爭議我已移除該文章,先跟您知會一聲,也說聲謝謝和抱歉~

blog comments powered by Disqus