http狀態碼全解讀

目錄

一、什麼是http狀態碼?

HTTP狀態碼(英語:HTTP Status Code)是用以表示網頁服務器超文本傳輸協議響應狀態的3位數字代碼(引自維基百科)。

這裏所說的超文本傳輸協議自然就是位於計算機網絡應用層的http協議(廣義上也包括https)。而響應狀態則是指,當客戶端向服務端發送請求時,服務端給出了何種類型的響應。按照RFC 2616的定義,http協議對每一種響應類型都給出了唯一對應的三位數字,每個數字稱爲一個狀態碼。目前總共有五大類狀態碼,分別對應五大類狀態,各以1-5開頭,它們的大致分類如下:

分類 分類描述
1xx 信息響應,表示服務器已收到請求,但是需要請求者繼續操作
2xx 響應成功,表示服務器已接收到請求並正確處理
3xx 重定向,表示服務器已接收到請求,但是沒有直接處理,而是進行了重定向
4xx 客戶端錯誤,表示客戶端發出的請求中存在錯誤,無法完成請求
5xx 服務端錯誤,表示服務器在處理請求的過程中出現錯誤

根據http狀態碼,開發或者運維可以大致瞭解http傳輸的狀態,從而在發生錯誤時快速鎖定問題範圍。

下面是目前規範所定義的所有狀態碼及其含義。

二、http狀態碼詳解

三級標題由兩部分構成,分別爲狀態碼的值,及狀態文本。狀態文本用於大致描述該狀態碼的含義。

1. 信息響應(1xx)

(1). 100 continue

這只是個臨時的響應狀態,它表示到目前爲止,客戶端請求的內容都沒有問題。但是客戶端需要繼續發送請求,才能完成本次請求過程。

(2). 101 Switching Protocol

服務器正在切換協議。

該代碼是響應客戶端的 Upgrade 標頭髮送的,並且指示服務器也正在切換的協議。比如,我們在使用ws協議時常會見到這個狀態碼。

從協議本身來說,http協議和ws協議並沒有什麼聯繫。前者是一個無狀態、短連接的協議,後者是一個有狀態、長連接的協議。但是爲了降低協議設計的複雜度,ws協議並沒有定義如何直接在客戶端和服務端建立一個ws連接,而是約定客戶端和服務端應該先建立一個http連接,然後由客戶端發送一個切換協議的請求,兩者再從http協議切換到ws協議。

服務器在切換協議的時候,就會向客戶端返回狀態碼101。

(3). 102 Processing

服務端已收到請求,正在處理中,但無響應可用。

簡言之,服務端正在處理當前請求。

(4). 103 Early Hints

預加載提示。此狀態代碼主要用於與Link 鏈接頭一起使用,以允許用戶代理在服務器仍在準備響應時開始預加載資源。

下面的標籤會發起一個預加載請求:

<link rel='preload' as='script' href='/js/index.js'>

由於設置了rel='preload',這個link標籤只是提前告訴瀏覽器,這裏描述的資源很快就會用到,請提前下載好。瀏覽器下載完該資源後並不會執行,而是等到需要執行時纔會執行:

<link rel='preload' as='script' href='/js/index.js'>
...
<!-- 這一行纔會執行index.js的代碼 -->
<script src='/js/index.js'></script>

這樣瀏覽器便可以同時渲染DOM和下載腳本,這通常可以帶來頁面性能的提升。

狀態碼103就表示當前請求的類型爲預加載類型。

2. 響應成功(2xx)

這是開發和運維最希望看到的一組狀態碼,它們的含義如下:

(1). 200 OK

請求成功。

表示當前請求被正確處理和返回。對不同的http方法來說,它的含義略有差異:

  • GET:資源已被提取並放置在消息正文中。
  • HEAD:實體表頭位於消息正文中。
  • POST:描述動作結果的資源在消息體中傳輸。
  • TRACE:消息正文包含服務器收到的請求消息。

(2). 201 Created

請求已成功,並因此創建了一個新的資源。當請求類型爲POST或PUT時,服務端可能會返回這個狀態碼。

(3). 202 Accepted

請求已收到,但還未響應,因此沒有結果。

不同於狀態碼102,返回狀態碼202意味着服務端之後不會再給出響應來表明該請求的處理結果(102表示請求未完結,服務端後續會繼續給出響應)。服務器可能將這個請求交給了其他進程或服務,或者執行了批處理。

(4). 203 Non-Authoritative Information

服務器已成功處理了請求,但返回的實體頭部元信息不是在原始服務器上有效的確定集合,而是來自本地或者第三方的拷貝。當前的信息可能是原始版本的子集或者超集。例如,包含資源的元數據可能導致原始服務器知道元信息的超集。

使用此狀態碼不是必須的,而且只有在響應不使用此狀態碼便會返回200 OK的情況下才是合適的。

(5). 204 No Content

服務器已成功處理了請求,但沒有返回任何實體內容,並且瀏覽器不需要刷新或者重定向。

舉例來說,當客戶端提交了一個form表單,如果服務端正確處理並返回狀態碼200,那麼當前頁面通常會刷新或重定向。而如果服務端返回的狀態碼是204的話,瀏覽器將不會刷新當前頁面,也不會重定向,而是僅僅收到請求成功的消息。如果我們需要更新頁面,可以在請求成功的回調函數中手動處理。

另外,如果a標籤發送的請求返回的狀態碼是204,那麼頁面也不會發生跳轉。

使用狀態碼204可以避免傳輸多餘的數據,以及某些不必要的頁面更新。

(6). 205 Reset Content

服務器已成功處理了請求,但沒有返回任何實體內容,不過瀏覽器應該立即刷新當前頁面。

該響應主要是被用於接受用戶輸入後,立即重置表單,以便用戶能夠輕鬆地開始另一次輸入。

(7). 206 Partical Content

服務器已經成功處理了部分 GET 請求。

這種情況常見於斷點續傳和大文檔分段。在使用類似迅雷這樣的http傳輸工具時,由於文檔一般較大,通常無法只使用一個get請求就下載完整個文檔,否則一旦傳輸過程中出現異常,整個文檔就不得不重新下載。另外,將文檔分成多個數據段,可以同時發送多個get請求,這樣可以提高下載速度,並且可以支持斷點續傳。

要實現這個需求,客戶端需要在GET請求中通過Range頭信息指定要下載的內容範圍,服務端每傳輸其中一段數據,就會發送一個206響應。

(8). 207 Multi-Status

這是由WebDAV擴展的狀態碼,代表之後的消息體將是一個XML消息,並且可能依照之前子請求數量的不同,包含一系列獨立的響應代碼。這是一個提示性的狀態碼。

(9). 208 Already Reported

在 DAV 裏面使用: propstat 響應元素以避免重複枚舉多個綁定的內部成員到同一個集合(引用自MDN,該狀態碼似乎不是面向http協議的,而是WebDAV)。

(10). 226 IM Used(HTTP Delta encoding)

服務器已經完成了對資源的 GET 請求,並且響應是對當前實例應用的一個或多個實例操作結果的表示。

3. 重定向(3xx)

(1). 300 Multiple Choice

被請求的資源有多個可供選擇的回饋信息,每個都有自己特定的地址和瀏覽器驅動的商議信息。用戶或瀏覽器能夠自行選擇一個首選的地址進行重定向。

即客戶端的請求存在多個可用資源時,客戶端需要繼續選擇其中一個。

(2). 301 Moved Permanently

被請求的資源已永久移動到新位置,並且將來任何對此資源的引用都應該使用本響應返回的若干個 URI 之一。

收到該狀態碼錶示當前要請求的資源位置發生了變更,需要使用當前響應返回的新的資源地址進行請求。一般來說,客戶端應當自動在收到301狀態碼時根據返回結果自動重置資源地址,以防止下次請求資源再次返回301

(3). 302 Found

請求的資源被臨時重定向到了別的URI。但這個重定向只是臨時的,下次請求當前資源時仍然應該使用當前的地址(即客戶端不需要像收到狀態碼301那樣修改資源地址)。

這個狀態碼對應的響應數據一般來說不會被緩存,除非明確指定了Cache-Control或Expires。

(4). 303 See Other

當前請求的響應結果可以從另一個URI請求到,而且客戶端應該使用GET方法進行請求。

當客戶端向服務端發送POST(或PUT、DELETE)請求時,如果服務端返回狀態碼303,表示服務端已經收到請求,但是不會進行處理。客戶端需要向響應中攜帶的新的URI發送GET請求,服務端纔會進行處理(圖片來自網絡)。在這裏插入圖片描述
響應中的location就是客戶端下次發送GET請求的地址。

(5). 304 Not Modified

未修改。

該響應碼非常常見,它表示當前資源已被下載過,並且沒有改變,因此客戶端應該從緩存中獲取該資源。比如在刷新頁面時,如果某個資源的狀態碼是304,通常表明它來自於瀏覽器緩存。

注意,304狀態碼禁止攜帶消息體,並且只用於GET請求。

(6). 305 Use Proxy

當前資源需要使用指定的代理才能訪問。響應的Location域給出了代理所在的URI,客戶端需要向這個代理再次單獨發送一個請求才能獲取指定的資源。

(MDN文檔中305狀態碼後面的圖標似乎表明該狀態碼已經不被推薦使用)
在這裏插入圖片描述

(7). 306 unused

最新的規範中,306不再被使用。

(8). 307 Temporary Redirect

請求的資源現在臨時從不同的 URI 響應請求。由於這樣的重定向是臨時的,客戶端應當繼續向原有地址發送以後的請求。只有在Cache-Control或Expires中進行了指定的情況下,這個響應纔是可緩存的。

可以看到,它的含義與狀態碼302是幾乎一致的。實際上,302是在http1.0中定義的,而303307是在http1.1中定義的。http1.1希望用這兩個更精確的狀態碼取代http1.0中的302,但是由於302已被廣泛引用與生產,而另外兩個狀態碼暫未得到很好的支持,因此目前還是以302的使用爲主(三者的關係參考文章HTTP狀態碼302、303和307的故事)。

(9). 308 Permanent Redirect

被請求的資源已永久移動到新位置,並且將來任何對此資源的引用都應該使用本響應返回的若干個 URI 之一,並且不應該修改請求方法。

它的含義與301 Moved Permanently是一致的,但是它有一個特殊的要求,就是在請求新的地址的時候,必須使用當前的請求方法。也就是說,如果當前發送的是POST請求,那麼新的請求也要使用POST方法。

4. 客戶端錯誤(4xx)

(1). 400 Bad Request

請求有誤。它包含兩種情況:

  1. 語義有誤。服務端無法理解當前請求的含義,因此客戶端必須對請求進行修改纔可以重新發送。
  2. 參數有誤。客戶端請求中攜帶的參數不符合服務端的要求,如數量不一致,類型錯誤,體積過大(如上傳文件時,文件大小超出了服務端配置)等。

(2). 401 Unauthorized

未授權。即當前請求需要進行用戶驗證。

該響應應該包含一個WWW-Authenticate信息頭以詢問用戶信息。客戶端需要在下次請求中攜帶合法的用戶驗證證書才能得到正確的響應。

如果客戶端的上次請求中已經攜帶了用戶證書,服務端仍然返回狀態碼401,就表示服務端拒絕了這些證書(即證書無效)。如果瀏覽器再次發送該請求,且再次被拒絕時,客戶端應該向用戶展示響應中的實體信息,因爲這裏可能包含了證書被拒絕的原因。

(3). 402 Payment Required

該狀態碼暫未使用,將來可能用於數字支付系統。

(4). 403 Forbidden

服務器已經接受並理解了請求,但是拒絕執行。

不同於401,這個狀態並不是身份驗證導致的,並且該請求不應該被再次提交(因爲仍然會被拒絕)。

如果這不是一個HEAD請求,而且服務器希望提供拒絕該請求的原因,可以在響應體中描述拒絕的原因。如果服務端不希望提供拒絕的原因,也可以直接返回狀態碼404

(5). 404 Not Found

請求的資源不存在。

當服務器無法找到客戶端所要請求的資源,並且無法(或者不想)解釋到哪裏找到這些資源時,常常會用到這個狀態碼。這個狀態碼無法告訴客戶端資源不存在是暫時的還是永久的,也不會提供跳轉地址,只是籠統地告訴客戶端當前請求的資源不存在。

如果服務器明確知道某些資源已經被刪除,並且想要告知客戶端,可以使用狀態碼410

(6). 405 Method Not Allowed

請求方法不允許。

比如服務端設置某個資源只能用POST方法進行訪問,而客戶端發送的是一個GET請求,服務端就會返回狀態碼405,表示當前方法不能請求到該資源。該響應必須在Allow響應頭中羅列出當前資源支持的請求方法列表。

由於PUT、DELETE等方法會對服務器上的資源執行寫操作,因此在服務端沒有明確指定的情況下發送這類請求,都會收到狀態碼405

(7). 406 Not Acceptable

請求的資源的內容特性無法滿足請求頭中的條件,因此無法生成響應實體。

比如客戶端設置返回的數據類型必須是JSON,而服務端沒有配置轉換JSON所依賴的包,或者所請求的資源本身就無法轉化爲JSON,這時服務端就無法生成符合客戶端要求的響應實體,因此就會返回狀態碼406

(8). 407 Proxy Authentication Required

需要在代理服務器上進行身份驗證。

該狀態碼與401 Unauthorized類似,但是它要求客戶端必須在代理服務器上進行身份驗證。代理服務器需要返回一個Proxy-Authenticate字段給客戶端,客戶端將這個字段的值發送給服務器進行身份驗證。

(9). 408 Request Timeout

請求超時。

當前請求沒有在指定的時間內收到響應。客戶端可以在不作任何修改的情況下,重新發送該請求。

(10). 409 Conflict

當前請求與所請求資源的狀態存在衝突,請求無法完成。

比如某個資源在特定情況下不可用,而服務器認爲客戶端能夠解決這個衝突,就可以返回409,並且在響應信息中描述資源衝突的原因,以幫助用戶解決衝突,重新請求資源。

如果服務端認爲客戶端無法解決該衝突,則不應該使用該狀態碼。

(11). 410 Gone

含義類似於404,表示請求的資源在服務器上已經不可用,並且沒有可轉發的地址。

一般來說,返回410的資源應該是永久不可用的。客戶端收到410時應當刪除所有指向該資源的請求,以防止繼續請求這個已經不存在的資源。如果服務端無法知道資源是否永久不可用,應該使用更常規的狀態碼404

(12). 411 Length Required

服務端拒絕沒有Content-Length參數的請求。

此時客戶端應該在消息頭內添加描述消息體長度的參數Content-Length再重新發送請求。

(13). 412 Precondition Failed

先決條件驗證失敗。

客戶端可以在請求資源時,在請求頭中描述所要請求的資源需要滿足的先決條件,如果服務器發現該資源不符合客戶端設置的先決條件,就會返回狀態碼412。這樣可以避免該請求方法被用於非客戶端需要的資源之上。

(14). 413 Payload Too Large

當前請求提交的數據量過大,服務端拒絕(或無法)處理。

此時服務端可以選擇關閉連接,以避免客戶端繼續發送此類請求。如果這個狀況是臨時的,服務端可以返回一個Retry-After響應頭,以告知客戶端在多久以後可以重新發送該請求。

(15). 414 URI Too Long

請求的URI過長,服務端無法解釋,因此拒絕該請求。

比如,一個本應通過POST提交的表單,現在被通過GET方法提交,整個表單的數據全部被作爲查詢參數添加到了URI中,就可能導致查詢字符串過長,服務端無法處理,從而返回414

(16). 415 Unsupported Media Type

對於當前請求的方法和所請求的資源,請求中提交的實體並不是服務器中所支持的格式,因此請求被拒絕。

即客戶端提交的數據格式不被服務器支持。

(17). 416 Range Not Satisfiable

如果請求頭包含了Rage參數,並且其指定的數據範圍與當前資源不重合,同時沒有定義If-Range字段,服務器就會返回416

比如某個文件的大小爲100kB,而當前請求要下載200kB-300kB範圍內的數據,就會得到416的報錯。

(18). 417 Expectation Failed

此響應代碼意味着服務器無法滿足 Expect 請求標頭字段指示的期望值。

Expect域包含了客戶端對服務端的期望條件,只有滿足了這個期望條件,才能繼續執行請求。目前Expect字段僅支持一個值:100-Continue,客戶端通過設置Expect的值爲100-Continue,來通知服務器接下來客戶端將發送一個體積很大的消息體,並詢問服務端是否要繼續。服務端可以給出以下兩個狀態碼響應:

  1. 100,表示服務器允許客戶端發送這個體積很大的請求,並等待客戶端的後續請求。
  2. 417,服務端拒絕接收這個體積很大的請求。

(19). 418 I’m a teapot

我是一個茶壺,不能用來衝咖啡。

這個狀態碼是1998年的愚人節提交的,帶有一定的幽默成分。它的原義是:當你向服務端發送一個“衝咖啡”的請求時,服務器會返回給你一個418的狀態碼,告訴你“我是一個茶壺,不要用我來衝咖啡”。

實際上大部分的服務器並沒有實現這個狀態碼,只是將其作爲一個愚人節玩笑看待。比如當用戶使用GET請求提交表單的時候,你就可以在服務端向客戶端返回一個418狀態碼。因爲GET請求是用來獲取資源的,而不是用來提交數據的,這就像你在拿“茶壺”衝“咖啡”一樣。

(20). 421 Misdirected Request

該請求針對的是無法產生響應的服務器。 這可以由服務器發送,該服務器未配置爲針對包含在請求 URI 中的方案和權限的組合產生響應。

換句話說,對於某些特定的URI,服務器無法作出響應。

(21). 422 Unprocessable Entity (WebDAV)

請求格式良好,但由於語義錯誤而無法遵循。

在講狀態碼400 Bad Request時,我們說到,它可以表示請求的語義錯誤,或請求參數錯誤;而415 Unsupported Media Type則用於描述請求參數的格式錯誤。

那麼當服務端明確知道當前錯誤是請求的語義錯誤時,就可以返回狀態碼422

(22). 423 Locked

當前所請求的資源暫時被鎖定。

(23). 424 Failed Dependency

由於當前請求所依賴的請求失敗,所以當前請求也失敗。

(24). 425 Too Early

服務器不願意冒風險來處理該請求,原因是處理該請求可能會被“重放”,從而造成潛在的重放攻擊。

所謂的重放攻擊,指的是當某個用戶在認證過程中,其認證信息被第三方竊取。這個第三方可能假冒當前用戶的身份向服務器重新發出身份認證的請求,從而假冒該用戶的身份。服務器認爲當前請求可能存在這種情況時,可以返回425拒絕用戶的請求。

(25). 426 Upgrade Required

服務器拒絕在當前協議下執行該請求,希望客戶端切換到其他協議。

服務端需要在響應消息的Upgrade參數中指明客戶端需要升級到何種協議纔可以發送請求。

(26). 428 Precondition Required

服務器要求客戶端的請求中必須攜帶某些條件,一般這意味着請求中缺少了必要的If-Match字段。

該狀態碼可以防止“更新丟失”。即客戶端讀取服務器上的某個資源,進行修改並返回給服務器的過程中,如果存在一個第三方也在修改該資源的狀態,那麼先被提交的更新就會丟失。服務端要求客戶端必須設置更新資源的條件,否則就返回428

(27). 429 Too Many Requests

請求頻率過高。

用戶在給定的時間內發送了過多的請求,服務端可以對限制數量以外的請求返回這個狀態碼,以防止服務器性能受到損失。

(28). 431 Request Header Fields Too Large

請求頭過大,服務器拒絕處理該請求。

客戶頓需要在減小請求頭大小後重新發送該請求。

(29). 451 Unavailable For Legal Reasons

非法資源。

它表示當前資源由於法律原因不可用,如被政府審查的網頁等。

5. 服務端錯誤(5xx)

(1). 500 Internal Server Error

服務器內部錯誤。

返回該狀態碼意味着服務器遇到了未知的錯誤,是一個通用的服務器錯誤的狀態碼。

(2). 501 Not Implemented

請求所用方法暫未被服務器實現,因此無法處理。

只有GET和HEAD是要求服務器必須支持的,這兩個方法不可能返回501。其他的方法如果服務器暫未實現,可以向客戶端返回一個501

(3). 502 Bad Gateway

網關錯誤。

它表示作爲網關或代理角色的服務器,從上游服務器(如tomcat、php-fpm)中接收到的響應是無效的。

Gateway(網關)在計算機網絡體系中可以指代不同的設備,502 錯誤通常不是客戶端能夠修復的,而是需要由途經的Web服務器或者代理服務器對其進行修復。

(4). 503 Service Unavailable

服務器沒有準備好處理請求。

比如服務器因維護或重載而停機。這時服務端一般需要返回一個友好的提示頁面,同時在響應消息中給出預計的恢復時間,以使客戶端了解問題原因及處理方法。

(5). 504 Gateway Timeout

作爲網關使用的服務器,因沒有及時得到響應而返回該錯誤代碼。這裏所說的響應,是其上游服務器的響應。

(6). 505 HTTP Version Not Supported

服務器不支持請求中所使用的的http版本。

(7). 506 Variant Also Negotiates

服務器存在內部配置錯誤。該狀態碼會出現在TCN(透明內容協商,見RF2295)上下文中(參考MDN - 506 Variant Also Negotiates)。

TCN協議允許客戶端取回給定資源的最佳變量/變元,具體取哪個變量/變元需要經過一個內容協商機制。而如果備選的變量/變元參與到了這個內容協商機制中,就會出現循環引用的錯誤,服務端將返回錯誤碼506

(8). 507 Insufficient Storage

服務器存在內部配置錯誤。

所選的變體資源被配置爲參與透明內容協商本身,因此服務器拒絕進行存儲。適用場景同上。

(9). 508 Loop Detected (WebDAV)

服務器在執行請求時檢測到了無限循環,因此終止了執行。

(10). 510 Not Extended

客戶端需要對請求進一步擴展,服務器才能實現它。服務器會回覆客戶端發出擴展請求所需的所有信息。

(11). 511 Network Authentication Required

客戶端需要進行身份認證才能獲得網絡訪問權限。

總結

以上是MDN列舉出的所有目前在用的http狀態碼,對於原文檔解釋得不是很清楚的部分,本文結合網上的一些文章進行了進一步說明,希望對從事web開發的同學帶來一些幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章