HTTP狀態碼,我都是現查現用。 我以前記得幾個常用的狀態碼,比如200,302,304,404, 503。 一般來說我也只需要了解這些常用的狀態碼就可以了。 如果是做AJAX,REST,網絡爬蟲,機器人等程序。還是需要了解其他狀態碼。 本文我花了一個多月的時間把所有的狀態碼都總結了下,內容太多,看的時候麻煩耐心點了。
HTTP狀態碼的學習資料到處都有,但是都是理論上講解。 本文介紹HTTP協議中的HTTP狀態碼(HTTP Status Code), 會對大部分的狀態碼都進行了詳細的實例講解。
要了解狀態碼,應該在實例中去理解狀態碼的意義,否則看了也會忘記的。
用Fiddler工具可以查看HTTP Request和Response, 還可以方便地查看Response中的狀態碼, 如果不熟悉這個工具,可以先參考【Fiddler教程】
為了重現HTTP 狀態碼,本文會使用Fiddler Composer來創建“特殊的HTTP Request”. 可以參考【Fiddler Composer創建和發送HTTP Request】
閱讀目錄
- 什么是HTTP狀態碼
- 狀態碼分類
- 常見的狀態碼
- 1XX 消息
- 2XX 成功
- 3XX 重定向
- 4XX 客戶端錯誤
- 5XX 服務器錯誤
- 204 No Content(沒有內容)
- 206 Partial Content(部分內容)
- 301 Moved Permanently(永久移除)
- 400 Bad Request(壞請求)
- 403 Forbidden(禁止)
- 405 Method Not Allowed(不允許使用的方法)
- 411 Length Required(要求長度指示)
- 413 Request Entity Too Large(請求實體太大)
- 414 Request URI Too Long(請求URI太長)
- 500 Internal Server Error(內部服務器錯誤)
- 501 Not Implemented(未實現)
- 502 Bad Gateway(網關故障)
- 505 HTTP Version Not Supported(不支持的HTTP版本)
什么是HTTP狀態碼
HTTP狀態碼的作用是:Web服務器用來告訴客戶端,發生了什么事。
狀態碼位於HTTP Response 的第一行中,會返回一個”三位數字的狀態碼“和一個“狀態消息”。 ”三位數字的狀態碼“便於程序進行處理, “狀態消息”更便於人理解。
如下圖, 當客戶端請求一個不存在的URL的時候, Web服務器會返回 “HTTP/1.1 404 Not Found” 告訴瀏覽器客戶端。 服務器無法找到所請求的URL。
狀態碼分類
HTTP狀態碼被分為五大類, 目前我們使用的HTTP協議版本是1.1, 支持以下的狀態碼。隨着協議的發展,HTTP規范中會定義更多的狀態碼。
小技巧: 假如你看到一個狀態碼518, 你並不知道具體518是什么意思。 這時候你只要知道518是屬於(5XX,服務器錯誤就可以了)
已定義范圍 | 分類 | |
1XX | 100-101 | 信息提示 |
2XX | 200-206 | 成功 |
3XX | 300-305 | 重定向 |
4XX | 400-415 | 客戶端錯誤 |
5XX | 500-505 | 服務器錯誤 |
常見的狀態碼
一般人只需要了解以下常見的狀態碼就夠了, 如果你想了解更多, 請繼續往下看。
200 OK 服務器成功處理了請求(這個是我們見到最多的) |
301/302 Moved Permanently(重定向)請求的URL已移走。Response中應該包含一個Location URL, 說明資源現在所處的位置 |
304 Not Modified(未修改)客戶的緩存資源是最新的, 要客戶端使用緩存 |
404 Not Found 未找到資源 |
501 Internal Server Error服務器遇到一個錯誤,使其無法對請求提供服務 |
1XX 信息性狀態碼
這些狀態碼是HTTP 1.1引入的。 對於這些狀態碼的價值還存在爭論 (我個人從來沒見過這些狀態碼, 也沒有理解這些狀態碼。)
狀態碼 | 狀態消息 | 含義 | 實例 |
100 | Continue(繼續) | 收到了請求的起始部分,客戶端應該繼續請求 | |
101 | Switching Protocols(切換協議) | 服務器正根據客戶端的指示將協議切換成Update Header列出的協議 |
2XX 成功狀態碼
客戶端發起請求時, 這些請求通常都是成功的。服務器有一組用來表示成功的狀態碼,分別對應於不同類型的請求。
狀態碼 | 狀態消息 | 含義 | 實例 |
200 | OK | 服務器成功處理了請求(這個是我們見到最多的) | HTTP協議詳解-200 |
201 | Created(已創建) | 對於那些要服務器創建對象的請求來說,資源已創建完畢。 | |
202 | Accepted(已接受) | 請求已接受, 但服務器尚未處理 | |
203 | Non-Authoritative Information(非權威信息) | 服務器已將事務成功處理,只是實體Header包含的信息不是來自原始服務器,而是來自資源的副本。 | |
204 | No Content(沒有內容) | Response中包含一些Header和一個狀態行, 但不包括實體的主題內容(沒有response body) | 狀態碼204 |
205 | Reset Content(重置內容) | 另一個主要用於瀏覽器的代碼。意思是瀏覽器應該重置當前頁面上所有的HTML表單。 | |
206 | Partial Content(部分內容) | 部分請求成功 | 狀態碼206 |
3XX 重定向狀態碼
重定向狀態碼用來告訴瀏覽器客戶端,它們訪問的資源已被移動, Web服務器發送一個重定向狀態碼和一個可選的Location Header, 告訴客戶端新的資源地址在哪。
瀏覽器客戶端會自動用Location中提供的地址,重新發送新的Request。 這個過程對用戶來說是透明的。
301和302 非常相似, 一個是永久轉移,一個是臨時轉移。
(SEO中,搜索引擎如果碰到301, 比如網頁A用301重定向到網頁B,搜索引擎可以肯定網頁A永久性改變地址,就會把網頁B當做唯一有效目標)
302,303,307 是一樣。 這是因為302是HTTP 1.0定義的, HTTP1.1中使用303,307. 同時又保留了302. (但在現實中,我們還是用302,我是沒見過303和307)
所以這一節, 我們只需要掌握302, 304 就可以了。
狀態碼 | 狀態消息 | 含義 | 實例 |
300 | Multiple Choices(多項選擇) | 客戶端請求了實際指向多個資源的URL。這個代碼是和一個選項列表一起返回的,然后用戶就可以選擇他希望的選項了 | |
301 | Moved Permanently(永久移除) | 請求的URL已移走。Response中應該包含一個Location URL, 說明資源現在所處的位置 | 狀態碼301 |
302 | Found(已找到) | 與狀態碼301類似。但這里的移除是臨時的。 客戶端會使用Location中給出的URL,重新發送新的HTTP request | HTTP協議詳解-302 |
303 | See Other(參見其他) | 類似302 | |
304 | Not Modified(未修改) | 客戶的緩存資源是最新的, 要客戶端使用緩存 | HTTP協議之緩存-304 |
305 | Use Proxy(使用代理) | 必須通過代理訪問資源, 代理的地址在Response 的Location中 | |
306 | 未使用 | 這個狀態碼當前沒使用 | |
307 | Temporary Redirect(臨時重定向 | 類似302 |
4XX客戶端錯誤狀態碼
有時客戶端會發送一些服務器無法處理的東西,比如格式錯誤的Request, 或者最常見的是, 請求一個不存在的URL。
狀態碼 | 狀態消息 | 含義 | 實例 |
400 | Bad Request(壞請求) | 告訴客戶端,它發送了一個錯誤的請求。 | 狀態碼400 |
401 | Unauthorized(未授權) | 需要客戶端對自己認證 | HTTP協議之基本認證-401 |
402 | Payment Required(要求付款) | 這個狀態還沒被使用, 保留給將來用 | |
403 | Forbidden(禁止) | 請求被服務器拒絕了 | 狀態碼403 |
404 | Not Found(未找到) | 未找到資源 | HTTP協議詳解-404 |
405 | Method Not Allowed(不允許使用的方法) | 不支持該Request的方法。 | 狀態碼405 |
406 | Not Acceptable(無法接受) | ||
407 | Proxy Authentication Required(要求進行代理認證) | 與狀態碼401類似, 用於需要進行認證的代理服務器 | HTTP協議之代理-407 |
408 | Request Timeout(請求超時) | 如果客戶端完成請求時花費的時間太長, 服務器可以回送這個狀態碼並關閉連接 | |
409 | Conflict(沖突) | 發出的請求在資源上造成了一些沖突 | |
410 | Gone(消失了) | 服務器曾經有這個資源,現在沒有了, 與狀態碼404類似 | |
411 | Length Required(要求長度指示) | 服務器要求在Request中包含Content-Length。 | 狀態碼411 |
412 | Precondition Failed(先決條件失敗) | ||
413 | Request Entity Too Large(請求實體太大) | 客戶端發送的實體主體部分比服務器能夠或者希望處理的要大 | 狀態碼413 |
414 | Request URI Too Long(請求URI太長) | 客戶端發送的請求所攜帶的URL超過了服務器能夠或者希望處理的長度 | 狀態碼414 |
415 | Unsupported Media Type(不支持的媒體類型) | 服務器無法理解或不支持客戶端所發送的實體的內容類型 | |
416 | Requested Range Not Satisfiable(所請求的范圍未得到滿足) | ||
417 | Expectation Failed(無法滿足期望) |
5XX服務器錯誤狀態碼
有時候客戶端發送了一條有效Request, Web服務器自身卻出錯了。 可能是Web服務器運行出錯了, 或者網站都掛了。 5XX就是用來描述服務器錯誤的。
狀態碼 | 狀態消息 | 含義 | 實例 |
500 | Internal Server Error(內部服務器錯誤) | 服務器遇到一個錯誤,使其無法為請求提供服務 | 狀態碼500 |
501 | Not Implemented(未實現) | 客戶端發起的請求超出服務器的能力范圍(比如,使用了服務器不支持的請求方法)時,使用此狀態碼。 | 狀態碼501 |
502 | Bad Gateway(網關故障) | 代理使用的服務器遇到了上游的無效響應 | 狀態碼502 |
503 | Service Unavailable(未提供此服務) | 服務器目前無法為請求提供服務,但過一段時間就可以恢復服務 | |
504 | Gateway Timeout(網關超時) | 與狀態嗎408類似, 但是響應來自網關或代理,此網關或代理在等待另一台服務器的響應時出現了超時 | |
505 | HTTP Version Not Supported(不支持的HTTP版本) | 服務器收到的請求使用了它不支持的HTTP協議版本。 有些服務器不支持HTTP早期的HTTP協議版本,也不支持太高的協議版本 | 狀態碼505 |
204 No Content(沒有內容)
返回的Response中只有一些Header和一個狀態行, 沒有實體的主題內容(沒有response body)
204狀態碼的作用在於: 1. 在不獲取資源的情況下了解資源的情況(比如判斷其類型)
2. 通過查看Response中的狀態碼, 看看某個對象是否存在
3. 通過查看Header, 測試資源是否被修改了。
實例:先打開Fiddler, 然后啟動瀏覽器訪問ditu.google.cn, 你會捕獲到很多204
206 Partial Content(部分內容)
206狀態碼代表服務器已經成功處理了部分GET請求(只有發送GET 方法的request, web服務器才可能返回206),
應用場景:
1. FlashGet, 迅雷或者HTTP下載工具都是使用206狀態碼來實現斷點續傳
2. 將以個大文檔分解為多個下載段同時下載 比如,在線看視頻
實例: 一些流媒體技術比如在線視頻,可以邊看邊下載。 就是使用206來實現的。
打開Fiddler, 然后用瀏覽器打開“搜狐視頻中的綠箭俠” http://tv.sohu.com/20121011/n354681393.shtml 然后你在Fiddler中就能看到一堆的206
1. 瀏覽器發送一個Get 方法的request. header中包含 Range: bytes=5303296-5336063. (意思就是請求得到5303296-5336063這個范圍的數據)。
2. Web服務器返回一個206 的Response. header中包含Content-Range: bytes 5303296-5336063/12129376(表明這次返回的內容范圍)
301 Moved Permanently(永久移除)
請求的URL已移走。Response中應該包含一個Location URL, 說明資源現在所處的位置
例如: 1. 瀏覽器客戶端訪問 http://map.google.cn
2. Web服務器返回Response 301,Location=http://titu.google.cn (告訴客戶端我們的資源位於這里, )
3. 瀏覽器客戶端會自動再發送一個Request 去訪問http://titu.google.cn
400 Bad Request(壞請求)
發送的Request中的數據有錯誤(比如:表單有錯誤,Cookie有錯誤), 這個我們也經常見到。
實例: 還沒想到, 想到了再貼個實例上來。
403 Forbidden(禁止)
Web客戶端發送的請求被Web服務器拒絕了, 如果服務器想說明為什么拒絕請求,可以包含實體的主體部分來對原因進行描述。但這個狀態碼通常是服務器不想說明拒絕原因。
訪問下面的URL, 會被服務器拒絕. 並且返回403狀態碼
http://t2.baidu.com/it/u=1791561788,200960144&fm=0&gp=0.jpg
404 Page not Found (請求的資源不存在)
這個大家都懂的, 值得一提的是: 騰訊把404頁面做成了“尋找被拐兒童”
405 Method Not Allowed(不允許使用的方法)
405是指Web服務器不支持Request中的方法。
我個人認為狀態碼405Method Not Allowed和501 Not Implemented 是一樣的意思。都是不支持Request的方法。 (目前我還不知道這兩個的區別)
實例: 發送一個是trace方法的Request 給www.google.com
411 Length Required(要求長度指示)
服務器要求在Request中包含Content-Length。
當瀏覽器使用Post方法,發送數據給Web服務器時, 必須要有Content-Length。這樣Web服務器才知道你要發送多少數據,否則Web服務器會返回411狀態碼
實例: 發送一個Post方法的Request 給www.google.com. Request中沒有Content-Length
413 Request Entity Too Large(請求實體太大)
作用:客戶端發送的實體主體部分比服務器能夠或者希望處理的要大。 一般情況下我們看不到這個狀態碼。 因為瀏覽器不會發送太大的數據給網站,但是機器人可能會。
實例: 用post方法發送一個大文件(100MB以上)給www.google.com
414 Request URI Too Long(請求URI太長)
就是說Request URI太長, 一般瀏覽器本身對URI的長度就會有限制,所以不會發送URI很長的Request. 我們平常是根本看不到414錯誤的。 但是機器人可以發送很長URI。
例如:我們用Fiddler Composer發送一個很長的URI給Google, 比如 "www.google.com?q=asdfasdasf.." q=后面的參數很長。 就可以看到414了
500 Internal Server Error(內部服務器錯誤)
這個太常見了, 我們開發網站的時候,當我們的程序出錯了時,就會返回500錯誤。
實例:ASP.NET 程序出錯
501 Not Implemented(未實現)
客戶端發起的請求超出服務器的能力范圍(比如,使用了服務器不支持的請求方法)時,使用此狀態碼)。 一般的Web服務器只支持GET和POST方法。
實例: 使用Fiddler Composer 給www.qq.com, 發送一個OPTIONS 方法的Request. 服務器就能返回501了。
502 Bad Gateway(網關故障)
代理使用的服務器遇到了上游的無效響應。
Fiddler本身就是代理服務器。 當我們訪問www.facebook.com,這網站被我們天朝屏蔽了。 所以我們可以得到502
505 HTTP Version Not Supported(不支持的HTTP版本)
表示Web服務器不支持此HTTP協議的版本。
眾所周知我們現在使用的HTTP協議版本是HTTP/1.1, 如果我們發送一個HTTP/2.0 的request 給博客園, 博客園肯定不能支持HTTP/2.0,所以會返回505
想要發送這樣的request, 可以使用Fiddler工具中的Composer來發送自定義的request, 如下圖。
[本文參考了: HTTP:The Definitive Guide]