一篇文章带你详解 HTTP 协议(下)
文章目錄,方便閱讀:
一、概述(已講)
二、HTTP 工作過程(已講)
三、HTTP 協議基礎(已講)
四、HTTP 協議報文結構(已講)
五、HTTP 報文首部之請求行、狀態行(已講)
六、HTTP 報文首部之首部字段(重點分析)(已講)
在上一篇中,我們已經講解了一到六的內容,還沒看過的可以先去看下前面的內容:
一篇文章帶你詳解 HTTP 協議(上)
一篇文章帶你詳解 HTTP 協議之報文首部及字段詳解(中)
?
下面接著講剩余內容:
七、HTTP 響應狀態碼(重點分析)
八、HTTP 報文實體
九、與 HTTP 協作的 Web 服務器
配套思維導圖:
七、HTTP 響應狀態碼(重點分析)
1. 狀態碼概述
-
HTTP 狀態碼負責表示客戶端 HTTP 請求的返回結果、標記服務器端的處理是否正常、通知出現的錯誤等工作。
-
HTTP 狀態碼如?200 OK?,以 3 位數字和原因短語組成。數字中的第一位指定了響應類別,后兩位無分類。
-
不少返回的響應狀態碼都是錯誤的,但是用戶可能察覺不到這點。比如 Web 應用程序內部發生錯誤,狀態碼依然返回?200 OK。
2. 狀態碼類別
| 1xx | Informational(信息性狀態碼) | 接收的請求正在處理 |
| 2xx | Success(成功狀態碼) | 請求正常處理完畢 |
| 3xx | Redirection(重定向狀態碼) | 需要進行附加操作以完成請求 |
| 4xx | Client Error(客戶端錯誤狀態碼) | 服務器無法處理請求 |
| 5xx | Server Error(服務器錯誤狀態碼) | 服務器處理請求出錯 |
我們可以自行改變 RFC2616 中定義的狀態碼或者服務器端自行創建狀態碼,只要遵守狀態碼的類別定義就可以了。
3. 常用狀態碼解析
HTTP 狀態碼種類繁多,數量達幾十種。其中最常用的有以下 14 種,一起來看看。
3.1 200 OK
表示從客戶端發來的請求在服務器端被正常處理了。
3.2 204 No Content
-
代表服務器接收的請求已成功處理,但在返回的響應報文中不含實體的主體部分。另外,也不允許返回任何實體的主體。
-
一般在只需要從客戶端向服務器端發送消息,而服務器端不需要向客戶端發送新消息內容的情況下使用。
3.3 206 Partial Content
表示客戶端進行了范圍請求,而服務器成功執行了這部分的 GET 請求。響應報文中包含由 Content-Range 首部字段指定范圍的實體內容。
3.4 301 Moved Permanently
永久性重定向。表示請求的資源已被分配了新的 URI。以后應使用資源現在所指的 URI。也就是說,如果已經把資源對應的 URI 保存為書簽了,這時應該按 Location 首部字段提示的 URI 重新保存。
3.5 302 Found
-
臨時性重定向。表示請求的資源已被分配了新的 URI,希望用戶(本次)能使用新的 URI 訪問。
-
和?301 Moved Permanently?狀態碼相似,但?302 Found?狀態碼代表資源不是被永久移動,只是臨時性質的。換句話說,已移動的資源對應的 URI 將來還有可能發生改變。
3.6 303 See Other
-
表示由于請求的資源存在著另一個 URI,應使用 GET 方法定向獲取請求的資源。
-
303 See Other 和?302 Found?狀態碼有著相同的功能,但?303 See Other?狀態碼明確表示客戶端應采用 GET 方法獲取資源,這點與?302 Found?狀態碼有區別。
3.7 304 Not Modified
-
表示客戶端發送附帶條件的請求時,服務器端允許請求訪問的資源,但未滿足條件的情況。
-
304 Not Modified?狀態碼返回時,不包含任何響應的主體部分。
-
304 Not Modified?雖然被劃分到 3xx 類別中,但和重定向沒有關系。
3.8 307 Temporary Redirect
臨時重定向。該狀態碼與?302 Found?有著相同的含義。
3.9 400 Bad Request
-
表示請求報文中存在語法錯誤。當錯誤發生時,需修改請求的內容后再次發送請求。
-
另外,瀏覽器會像?200 OK?一樣對待該狀態碼。
3.10 401 Unauthorized
-
表示發送的請求需要有通過 HTTP 認證(BASIC 認證、DIGEST 認證)的認證信息。
-
另外,若之前已進行過 1 次請求,則表示用戶認證失敗。
-
返回含有?401 Unauthorized?的響應必須包含一個適用于被請求資源的 WWW-Authenticate 首部用以質詢(challenge)用戶信息。
3.11 403 Forbidden
表明對請求資源的訪問被服務器拒絕了。服務器端沒有必要給出詳細的拒絕理由,當然也可以在響應報文的實體主體部分對原因進行描述。
3.12 404 Not Found
表明服務器上無法找到請求的資源。除此之外,也可以在服務器端拒絕請求且不想說明理由的時候使用。
3.13 500 Internal Server Error
表明服務器端在執行請求時發生了錯誤。也可能是 Web 應用存在的 bug 或某些臨時的故障。
3.14 503 Service Unavailable
表明服務器暫時處于超負載或正在進行停機維護,現在無法處理請求。如果事先得知解除以上狀況需要的時間,最好寫入 Retry-After 首部字段再返回給客戶端。
?
八、HTTP 報文實體
1. HTTP 報文實體概述
HTTP 報文結構?
大家請仔細看看上面示例中,各個組成部分對應的內容。
接著,我們來看看報文和實體的概念。如果把 HTTP 報文想象成因特網貨運系統中的箱子,那么 HTTP 實體就是報文中實際的貨物。
-
報文:是網絡中交換和傳輸的數據單元,即站點一次性要發送的數據塊。報文包含了將要發送的完整的數據信息,其長短很不一致,長度不限且可變。
-
實體:作為請求或響應的有效載荷數據(補充項)被傳輸,其內容由實體首部和實體主體組成。(實體首部相關內容在上面第六點中已有闡述。)
我們可以看到,上面示例右圖中深紅色框的內容就是報文的實體部分,而藍色框的兩部分內容分別就是實體首部和實體主體。而左圖中粉紅框內容就是報文主體。
通常,報文主體等于實體主體。只有當傳輸中進行編碼操作時,實體主體的內容發生變化,才導致它和報文主體產生差異。
2. 內容編碼
-
HTTP 應用程序有時在發送之前需要對內容進行編碼。例如,在把很大的 HTML 文檔發送給通過慢速連接上來的客戶端之前,服務器可能會對其進行壓縮,這樣有助于減少傳輸實體的時間。服務器還可以把內容攪亂或加密,以此來防止未授權的第三方看到文檔的內容。
-
這種類型的編碼是在發送方應用到內容之上的。當內容經過內容編碼后,編好碼的數據就放在實體主體中,像往常一樣發送給接收方。
內容編碼類型:
| gzip | 表明實體采用 GNU zip 編碼 |
| compress | 表明實體采用 Unix 的文件壓縮程序 |
| deflate | 表明實體采用 zlib 的格式壓縮的 |
| identity | 表明沒有對實體進行編碼,當沒有 Content-Encoding 首部字段時,默認采用此編碼方式 |
3. 傳輸編碼
內容編碼是對報文的主體進行的可逆變換,是和內容的具體格式細節緊密相關的。
傳輸編碼也是作用在實體主體上的可逆變換,但使用它們是由于架構方面的原因,同內容的格式無關。使用傳輸編碼是為了改變報文中的數據在網絡上傳輸的方式。
?
4. 分塊編碼
分塊編碼把報文分割成若干已知大小的塊。塊之間是緊挨著發送的,這樣就不需要在發送之前知道整個報文的大小了。分塊編碼是一種傳輸編碼,是報文的屬性。
分塊編碼與持久連接
若客戶端與服務器端之間不是持久連接,客戶端就不需要知道它在讀取的主體的長度,而只需要讀取到服務器關閉主體連接為止。
當使用持久連接時,在服務器寫主體之前,必須知道它的大小并在 Content-Length 首部中發送。如果服務器動態創建內容,就可能在發送之前無法知道主體的長度。
分塊編碼為這種困難提供了解決方案,只要允許服務器把主體分塊發送,說明每塊的大小就可以了。因為主體是動態創建的,服務器可以緩沖它的一部分,發送其大小和相應的塊,然后在主體發送完之前重復這個過程。服務器可以用大小為 0 的塊作為主體結束的信號,這樣就可以繼續保持連接,為下一個響應做準備。
來看看一個分塊編碼的報文示例:
?
5.多部分媒體類型
MIME 中的 multipart(多部分)電子郵件報文中包含多個報文,它們合在一起作為單一的復雜報文發送。每一部分都是獨立的,有各自的描述其內容的集,不同部分之間用分界字符串連接在一起。
相應得,HTTP 協議中也采納了多部分對象集合,發送的一份報文主體內可包含多種類型實體。
多部分對象集合包含的對象如下:
-
multipart/form-data:在 Web 表單文件上傳時使用。
-
multipart/byteranges:狀態碼?206 Partial Content?響應報文包含了多個范圍的內容時使用。
6. 范圍請求
假設你正在下載一個很大的文件,已經下了四分之三,忽然網絡中斷了,那下載就必須重頭再來一遍。為了解決這個問題,需要一種可恢復的機制,即能從之前下載中斷處恢復下載。要實現該功能,這就要用到范圍請求。
有了范圍請求, HTTP 客戶端可以通過請求曾獲取失敗的實體的一個范圍(或者說一部分),來恢復下載該實體。當然這有一個前提,那就是從客戶端上一次請求該實體到這一次發出范圍請求的時間段內,該對象沒有改變過。例如:
?
上面示例中,客戶端請求的是文檔開頭20224字節之后的部分。
?
九、與 HTTP 協作的 Web 服務器
HTTP 通信時,除客戶端和服務器外,還有一些用于協助通信的應用程序。如下列出比較重要的幾個:代理、緩存、網關、隧道、Agent 代理。
1.代理
代理?
HTTP 代理服務器是 Web 安全、應用集成以及性能優化的重要組成模塊。代理位于客戶端和服務器端之間,接收客戶端所有的 HTTP 請求,并將這些請求轉發給服務器(可能會對請求進行修改之后再進行轉發)。對用戶來說,這些應用程序就是一個代理,代表用戶訪問服務器。
出于安全考慮,通常會將代理作為轉發所有 Web 流量的可信任中間節點使用。代理還可以對請求和響應進行過濾,安全上網或綠色上網。
2. 緩存
瀏覽器第一次請求:
瀏覽器第一次請求?
瀏覽器再次請求:
瀏覽器再次請求?
Web 緩存或代理緩存是一種特殊的 HTTP 代理服務器,可以將經過代理傳輸的常用文檔復制保存起來。下一個請求同一文檔的客戶端就可以享受緩存的私有副本所提供的服務了。客戶端從附近的緩存下載文檔會比從遠程 Web 服務器下載快得多。
3. 網關
HTTP / FTP 網關?
網關是一種特殊的服務器,作為其他服務器的中間實體使用。通常用于將 HTTP 流量轉換成其他的協議。網關接收請求時就好像自己是資源的源服務器一樣。客戶端可能并不知道自己正在跟一個網關進行通信。
4. 隧道
HTTP/SSL 隧道?
隧道是會在建立起來之后,就會在兩條連接之間對原始數據進行盲轉發的 HTTP 應用程序。HTTP 隧道通常用來在一條或多條 HTTP 連接上轉發非 HTTP 數據,轉發時不會窺探數據。
HTTP 隧道的一種常見用途就是通過 HTTP 連接承載加密的安全套接字層(SSL)流量,這樣 SSL 流量就可以穿過只允許 Web 流量通過的防火墻了。
5. Agent 代理
自動搜索引擎“網絡蜘蛛”?
Agent 代理是代表用戶發起 HTTP 請求的客戶端應用程序。所有發布 Web 請求的應用程序都是 HTTP Agent 代理。
總結
以上是生活随笔為你收集整理的一篇文章带你详解 HTTP 协议(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一篇文章带你详解 HTTP 协议之报文首
- 下一篇: 一篇文章带你详解 TCP/IP 协议(上