日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747


響應狀態碼該怎么用?

 

前兩講中,我們學習了 HTTP 報文里請求行的組成部分,包括請求方法和 URI。有了請求行,加上后面的頭字段就形成了請求頭,可以通過 TCP/IP 協議發送給服務器。

服務器收到請求報文,解析后需要進行處理,具體的業務邏輯多種多樣,但最后必定是拼出一個響應報文發回客戶端。

響應報文由響應頭加響應體數據組成,響應頭又由狀態行和頭字段構成。

我們先來復習一下狀態行的結構,有三部分:

響應狀態碼該怎么用?

 

開頭的 Version 部分是 HTTP 協議的版本號,通常是 HTTP/1.1,用處不是很大。

后面的 Reason 部分是原因短語,是狀態碼的簡短文字描述,例如“OK”“Not Found”等等,也可以自定義。但它只是為了兼容早期的文本客戶端而存在,提供的信息很有限,目前的大多數客戶端都會忽略它。

所以,狀態行里有用的就只剩下中間的狀態碼(Status Code)了。它是一個十進制數字,以代碼的形式表示服務器對請求的處理結果,就像我們通常編寫程序時函數返回的錯誤碼一樣。

不過你要注意,它的名字是“狀態碼”而不是“錯誤碼”。也就是說,它的含義不僅是錯誤,更重要的意義在于表達 HTTP 數據處理的“狀態”,客戶端可以依據代碼適時轉換處理狀態,例如繼續發送請求、切換協議,重定向跳轉等,有那么點 TCP 狀態轉換的意思。

狀態碼

目前 RFC 標準里規定的狀態碼是三位數,所以取值范圍就是從 000 到 999。但如果把代碼簡單地從 000 開始順序編下去就顯得有點太“low”,不靈活、不利于擴展,所以狀態碼也被設計成有一定的格式。

RFC 標準把狀態碼分成了五類,用數字的第一位表示分類,而 0~99 不用,這樣狀態碼的實際可用范圍就大大縮小了,由 000~999 變成了 100~599。

這五類的具體含義是:

  • 1××:提示信息,表示目前是協議處理的中間狀態,還需要后續的操作;
  • 2××:成功,報文已經收到并被正確處理;
  • 3××:重定向,資源位置發生變動,需要客戶端重新發送請求;
  • 4××:客戶端錯誤,請求報文有誤,服務器無法處理;
  • 5××:服務器錯誤,服務器在處理請求時內部發生了錯誤。

在 HTTP 協議中,正確地理解并應用這些狀態碼不是客戶端或服務器單方的責任,而是雙方共同的責任。

客戶端作為請求的發起方,獲取響應報文后,需要通過狀態碼知道請求是否被正確處理,是否要再次發送請求,如果出錯了原因又是什么。這樣才能進行下一步的動作,要么發送新請求,要么改正錯誤重發請求。

服務器端作為請求的接收方,也應該很好地運用狀態碼。在處理請求時,選擇最恰當的狀態碼回復客戶端,告知客戶端處理的結果,指示客戶端下一步應該如何行動。特別是在出錯的時候,盡量不要簡單地返 400、500 這樣意思含糊不清的狀態碼。

目前 RFC 標準里總共有 41 個狀態碼,但狀態碼的定義是開放的,允許自行擴展。所以 Apache、Nginx 等 Web 服務器都定義了一些專有的狀態碼。如果你自己開發 Web 應用,也完全可以在不沖突的前提下定義新的代碼。

在我們的實驗環境里也可以對這些狀態碼做測試驗證,訪問 URI“/12-1”,用查詢參數“code=xxx”來檢查這些狀態碼的效果,服務器不僅會在狀態行里顯示狀態碼,還會在響應頭里用自定義的“Expect-Code”字段輸出這個代碼。

例如,在 Chrome 里訪問“http://www.chrono.com/12-1?code=405”的結果如下圖。

響應狀態碼該怎么用?

 

接下來我就挑一些實際開發中比較有價值的狀態碼逐個詳細介紹。

1××

1××類狀態碼屬于提示信息,是協議處理的中間狀態,實際能夠用到的時候很少。

我們偶爾能夠見到的是“101 Switching Protocols”。它的意思是客戶端使用 Upgrade 頭字段,要求在 HTTP 協議的基礎上改成其他的協議繼續通信,比如 WebSocket。而如果服務器也同意變更協議,就會發送狀態碼 101,但這之后的數據傳輸就不會再使用 HTTP 了。

2××

2××類狀態碼表示服務器收到并成功處理了客戶端的請求,這也是客戶端最愿意看到的狀態碼。

200 OK”是最常見的成功狀態碼,表示一切正常,服務器如客戶端所期望的那樣返回了處理結果,如果是非 HEAD 請求,通常在響應頭后都會有 body 數據。

204 No Content”是另一個很常見的成功狀態碼,它的含義與“200 OK”基本相同,但響應頭后沒有 body 數據。所以對于 Web 服務器來說,正確地區分 200 和 204 是很必要的。

206 Partial Content”是 HTTP 分塊下載或斷點續傳的基礎,在客戶端發送“范圍請求”、要求獲取資源的部分數據時出現,它與 200 一樣,也是服務器成功處理了請求,但 body 里的數據不是資源的全部,而是其中的一部分。

狀態碼 206 通常還會伴隨著頭字段“Content-Range”,表示響應報文里 body 數據的具體范圍,供客戶端確認,例如“Content-Range: bytes 0-99/2000”,意思是此次獲取的是總計 2000 個字節的前 100 個字節。

3××

3××類狀態碼表示客戶端請求的資源發生了變動,客戶端必須用新的 URI 重新發送請求獲取資源,也就是通常所說的“重定向”,包括著名的 301、302 跳轉。

301 Moved Permanently”俗稱“永久重定向”,含義是此次請求的資源已經不存在了,需要改用改用新的 URI 再次訪問。

與它類似的是“302 Found”,曾經的描述短語是“Moved Temporarily”,俗稱“臨時重定向”,意思是請求的資源還在,但需要暫時用另一個 URI 來訪問。

301 和 302 都會在響應頭里使用字段Location指明后續要跳轉的 URI,最終的效果很相似,瀏覽器都會重定向到新的 URI。兩者的根本區別在于語義,一個是“永久”,一個是“臨時”,所以在場景、用法上差距很大。

比如,你的網站升級到了 HTTPS,原來的 HTTP 不打算用了,這就是“永久”的,所以要配置 301 跳轉,把所有的 HTTP 流量都切換到 HTTPS。

再比如,今天夜里網站后臺要系統維護,服務暫時不可用,這就屬于“臨時”的,可以配置成 302 跳轉,把流量臨時切換到一個靜態通知頁面,瀏覽器看到這個 302 就知道這只是暫時的情況,不會做緩存優化,第二天還會訪問原來的地址。

304 Not Modified” 是一個比較有意思的狀態碼,它用于 If-Modified-Since 等條件請求,表示資源未修改,用于緩存控制。它不具有通常的跳轉含義,但可以理解成“重定向已到緩存的文件”(即“緩存重定向”)。

301、302 和 304 分別涉及了 HTTP 協議里重要的“重定向跳轉”和“緩存控制”,在之后的課程中我還會細講。

4××

4××類狀態碼表示客戶端發送的請求報文有誤,服務器無法處理,它就是真正的“錯誤碼”含義了。

400 Bad Request”是一個通用的錯誤碼,表示請求報文有錯誤,但具體是數據格式錯誤、缺少請求頭還是 URI 超長它沒有明確說,只是一個籠統的錯誤,客戶端看到 400 只會是“一頭霧水”“不知所措”。所以,在開發 Web 應用時應當盡量避免給客戶端返回 400,而是要用其他更有明確含義的狀態碼。

403 Forbidden”實際上不是客戶端的請求出錯,而是表示服務器禁止訪問資源。原因可能多種多樣,例如信息敏感、法律禁止等,如果服務器友好一點,可以在 body 里詳細說明拒絕請求的原因,不過現實中通常都是直接給一個“閉門羹”。

404 Not Found”可能是我們最常看見也是最不愿意看到的一個狀態碼,它的原意是資源在本服務器上未找到,所以無法提供給客戶端。但現在已經被“用濫了”,只要服務器“不高興”就可以給出個 404,而我們也無從得知后面到底是真的未找到,還是有什么別的原因,某種程度上它比 403 還要令人討厭。

4××里剩下的一些代碼較明確地說明了錯誤的原因,都很好理解,開發中常用的有:

  • 405 Method Not Allowed:不允許使用某些方法操作資源,例如不允許 POST 只能 GET;
  • 406 Not Acceptable:資源無法滿足客戶端請求的條件,例如請求中文但只有英文;
  • 408 Request Timeout:請求超時,服務器等待了過長的時間;
  • 409 Conflict:多個請求發生了沖突,可以理解為多線程并發時的競態;
  • 413 Request Entity Too Large:請求報文里的 body 太大;
  • 414 Request-URI Too Long:請求行里的 URI 太大;
  • 429 Too Many Requests:客戶端發送了太多的請求,通常是由于服務器的限連策略;
  • 431 Request Header Fields Too Large:請求頭某個字段或總體太大;

5××

5××類狀態碼表示客戶端請求報文正確,但服務器在處理時內部發生了錯誤,無法返回應有的響應數據,是服務器端的“錯誤碼”。

500 Internal Server Error”與 400 類似,也是一個通用的錯誤碼,服務器究竟發生了什么錯誤我們是不知道的。不過對于服務器來說這應該算是好事,通常不應該把服務器內部的詳細信息,例如出錯的函數調用棧告訴外界。雖然不利于調試,但能夠防止黑客的窺探或者分析。

501 Not Implemented”表示客戶端請求的功能還不支持,這個錯誤碼比 500 要“溫和”一些,和“即將開業,敬請期待”的意思差不多,不過具體什么時候“開業”就不好說了。

502 Bad Gateway”通常是服務器作為網關或者代理時返回的錯誤碼,表示服務器自身工作正常,訪問后端服務器時發生了錯誤,但具體的錯誤原因也是不知道的。

503 Service Unavailable”表示服務器當前很忙,暫時無法響應服務,我們上網時有時候遇到的“網絡服務正忙,請稍后重試”的提示信息就是狀態碼 503。

503 是一個“臨時”的狀態,很可能過幾秒鐘后服務器就不那么忙了,可以繼續提供服務,所以 503 響應報文里通常還會有一個“Retry-After”字段,指示客戶端可以在多久以后再次嘗試發送請求。

小結

  1. 狀態碼在響應報文里表示了服務器對請求的處理結果;
  2. 狀態碼后的原因短語是簡單的文字描述,可以自定義;
  3. 狀態碼是十進制的三位數,分為五類,從 100 到 599;
  4. 2××類狀態碼表示成功,常用的有 200、204、206;
  5. 3××類狀態碼表示重定向,常用的有 301、302、304;
  6. 4××類狀態碼表示客戶端錯誤,常用的有 400、403、404;
  7. 5××類狀態碼表示服務器錯誤,常用的有 500、501、502、503。

課下作業

  1. 你在開發 HTTP 客戶端,收到了一個非標準的狀態碼,比如 4××、5××,應當如何應對呢?
  2. 你在開發 HTTP 服務器,處理請求時發現報文里缺了一個必需的 query 參數,應該如何告知客戶端錯誤原因呢?

歡迎你把自己的答案寫在留言區,與我和其他同學一起討論。如果你覺得有所收獲,歡迎你把文章分享給你的朋友。

分享到:
標簽:響應 狀態
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定