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