网络编程懒人入门(七):深入浅出,全面理解HTTP协议
轉自即時通訊網:http://www.52im.net/
本文引用了自簡書作者“滌生_Woo”的文章,內容有刪減,感謝原作者的分享。
1、前言
HTTP(全稱超文本傳輸協議,英文全稱HyperText Transfer Protocol)是互聯網上應用最為廣泛的一種網絡協議。所有的WWW文件都必須遵守這個標準。設計HTTP最初的目的是為了提供一種發布和接收HTML頁面的方法。
對于移動端即時通訊(尤其IM應用)來說,現今主流的數據通信總結下來無外乎就是長連接+短連接的方式,而短連接在應用上講就是本文將要介紹的HTTP協議的應用,正確地理解HTTP協議對于寫好IM來說,是相當有益的(關于移動端的HTTP具體應用情況,可以閱讀《現代移動端網絡短連接的優化手段總結:請求速度、弱網適應、安全保障》)。
本篇文章篇幅比較長,先來個思維導圖預覽一下:
2、“HTTP之父”
“HTTP之父”——Ted Nelson
HTTP協議logo
1960年Ted Nelson構思了一種通過計算機處理文本信息的方法,并稱之為超文本(hypertext),這成為了HTTP超文本傳輸協議標準架構的發展根基。
Ted Nelson組織協調萬維網協會(World Wide Web Consortium)和Internet工作小組(Internet Engineering Task Force)共同合作研究,最終發布了一系列的RFC,其中最著名的就是RFC 2616。RFC 2616定義了HTTP協議的我們今天普遍使用的一個版本——HTTP 1.1。
由于Ted Nelson對HTTP技術的發展做出的突破性歷史貢獻,他被稱為“HTTP之父”。
3、系列文章
本文是系列文章中的第7篇,本系列文章的大綱如下:
- 《網絡編程懶人入門(一):快速理解網絡通信協議(上篇)》
- 《網絡編程懶人入門(二):快速理解網絡通信協議(下篇)》
- 《網絡編程懶人入門(三):快速理解TCP協議一篇就夠》
- 《網絡編程懶人入門(四):快速理解TCP和UDP的差異》
- 《網絡編程懶人入門(五):快速理解為什么說UDP有時比TCP更有優勢》
- 《網絡編程懶人入門(六):史上最通俗的集線器、交換機、路由器功能原理入門》
- 《網絡編程懶人入門(七):深入淺出,全面理解HTTP協議》(本文)
- 《網絡編程懶人入門(八):手把手教你寫基于TCP的Socket長連接》
本站的《腦殘式網絡編程入門》也適合入門學習,本系列大綱如下:
- 《腦殘式網絡編程入門(一):跟著動畫來學TCP三次握手和四次揮手》
- 《腦殘式網絡編程入門(二):我們在讀寫Socket時,究竟在讀寫什么?》
- 《腦殘式網絡編程入門(三):HTTP協議必知必會的一些知識》
- 《腦殘式網絡編程入門(四):快速理解HTTP/2的服務器推送(Server Push)》
如果您覺得本系列文章過于基礎,您可直接閱讀《不為人知的網絡編程》系列文章,該系列目錄如下:
- 《不為人知的網絡編程(一):淺析TCP協議中的疑難雜癥(上篇)》
- 《不為人知的網絡編程(二):淺析TCP協議中的疑難雜癥(下篇)》
- 《不為人知的網絡編程(三):關閉TCP連接時為什么會TIME_WAIT、CLOSE_WAIT》
- 《不為人知的網絡編程(四):深入研究分析TCP的異常關閉》
- 《不為人知的網絡編程(五):UDP的連接性和負載均衡》
- 《不為人知的網絡編程(六):深入地理解UDP協議并用好它》
關于移動端網絡特性及優化手段的總結性文章請見:
- 《現代移動端網絡短連接的優化手段總結:請求速度、弱網適應、安全保障》
- 《移動端IM開發者必讀(一):通俗易懂,理解移動網絡的“弱”和“慢”》
- 《移動端IM開發者必讀(二):史上最全移動弱網絡優化方法總結》
?
4、參考資料
?
- 《TCP/IP詳解 - 第11章·UDP:用戶數據報協議》
- 《TCP/IP詳解 - 第17章·TCP:傳輸控制協議》
- 《TCP/IP詳解 - 第18章·TCP連接的建立與終止》
- 《TCP/IP詳解 - 第21章·TCP的超時與重傳》
- 《通俗易懂-深入理解TCP協議(上):理論基礎》
- 《通俗易懂-深入理解TCP協議(下):RTT、滑動窗口、擁塞處理》
- 《理論經典:TCP協議的3次握手與4次揮手過程詳解》
- 《理論聯系實際:Wireshark抓包分析TCP 3次握手、4次揮手過程》
- 《計算機網絡通訊協議關系圖(中文珍藏版)》
- 《高性能網絡編程(一):單臺服務器并發TCP連接數到底可以有多少》
- 《高性能網絡編程(二):上一個10年,著名的C10K并發連接問題》
- 《高性能網絡編程(三):下一個10年,是時候考慮C10M并發問題了》
- 《高性能網絡編程(四):從C10K到C10M高性能網絡應用的理論探索》
- 《簡述傳輸層協議TCP和UDP的區別》
- 《為什么QQ用的是UDP協議而不是TCP協議?》
- 《移動端即時通訊協議選擇:UDP還是TCP?》
5、HTTP概述
5.1計算機網絡體系結構分層
5.2 TCP/IP通信傳輸流
利用 TCP/IP 協議族進行網絡通信時,會通過分層順序與對方進行通信。發送端從應用層往下走,接收端則從鏈路層往上走。
TCP/IP 通信傳輸流如下:
- 首先作為發送端的客戶端在應用層(HTTP 協議)發出一個想看某個 Web 頁面的 HTTP 請求;
- 接著,為了傳輸方便,在傳輸層(TCP 協議)把從應用層處收到的數據(HTTP 請求報文)進行分割,并在各個報文上打上標記序號及端口號后轉發給網絡層;
- 在網絡層(IP 協議),增加作為通信目的地的 MAC 地址后轉發給鏈路層。這樣一來,發往網絡的通信請求就準備齊全了;
- 接收端的服務器在鏈路層接收到數據,按序往上層發送,一直到應用層。當傳輸到應用層,才能算真正接收到由客戶端發送過來的 HTTP請求。
HTTP 請求如下圖所示:
在網絡體系結構中,包含了眾多的網絡協議,這篇文章主要圍繞 HTTP 協議(HTTP/1.1版本)展開。
HTTP協議(HyperText Transfer Protocol,超文本傳輸協議)是用于從WWW服務器傳輸超文本到本地瀏覽器的傳輸協議。它可以使瀏覽器更加高效,使網絡傳輸減少。它不僅保證計算機正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內容首先顯示(如文本先于圖形)等。
HTTP是客戶端瀏覽器或其他程序與Web服務器之間的應用層通信協議。在Internet上的Web服務器上存放的都是超文本信息,客戶端需要通過HTTP協議傳輸所要訪問的超文本信息。HTTP包含命令和傳輸信息,不僅可用于Web訪問,也可以用于其他因特網/內聯網應用系統之間的通信,從而實現各類應用資源超媒體訪問的集成。
我們在瀏覽器的地址欄里輸入的網站地址叫做URL (Uniform Resource Locator,統一資源定位符)。就像每家每戶都有一個門牌地址一樣,每個網頁也都有一個Internet地址。當你在瀏覽器的地址框中輸入一個URL或是單擊一個超級鏈接時,URL就確定了要瀏覽的地址。瀏覽器通過超文本傳輸協議(HTTP),將Web服務器上站點的網頁代碼提取出來,并翻譯成漂亮的網頁。
6、HTTP工作過程
HTTP請求響應模型:
HTTP通信機制是在一次完整的 HTTP 通信過程中,客戶端與服務器之間將完成下列7個步驟:
- 1)建立 TCP 連接:在HTTP工作開始之前,客戶端首先要通過網絡與服務器建立連接,該連接是通過 TCP 來完成的,該協議與 IP 協議共同構建 Internet,即著名的 TCP/IP 協議族,因此 Internet 又被稱作是 TCP/IP 網絡。HTTP 是比 TCP 更高層次的應用層協議,根據規則,只有低層協議建立之后,才能進行高層協議的連接,因此,首先要建立 TCP 連接,一般 TCP 連接的端口號是80;
- 2)客戶端向服務器發送請求命令:一旦建立了TCP連接,客戶端就會向服務器發送請求命令;
例如:GET/sample/hello.jsp HTTP/1.1; - 3)客戶端發送請求頭信息:客戶端發送其請求命令之后,還要以頭信息的形式向服務器發送一些別的信息,之后客戶端發送了一空白行來通知服務器,它已經結束了該頭信息的發送;
- 4)服務器應答:客戶端向服務器發出請求后,服務器會向客戶端返回響應;
例如: HTTP/1.1 200 OK
響應的第一部分是協議的版本號和響應狀態碼; - 5)服務器返回響應頭信息:正如客戶端會隨同請求發送關于自身的信息一樣,服務器也會隨同響應向用戶發送關于它自己的數據及被請求的文檔;
- 6)服務器向客戶端發送數據:服務器向客戶端發送頭信息后,它會發送一個空白行來表示頭信息的發送到此為結束,接著,它就以 Content-Type 響應頭信息所描述的格式發送用戶所請求的實際數據;
- 7)服務器關閉 TCP 連接:一般情況下,一旦服務器向客戶端返回了請求數據,它就要關閉 TCP 連接,然后如果客戶端或者服務器在其頭信息加入了這行代碼 Connection:keep-alive ,TCP 連接在發送后將仍然保持打開狀態,于是,客戶端可以繼續通過相同的連接發送請求。保持連接節省了為每個請求建立新連接所需的時間,還節約了網絡帶寬。
7、HTTP協議基礎
7.1通過請求和響應的交換達成通信
應用 HTTP 協議時,必定是一端擔任客戶端角色,另一端擔任服務器端角色。僅從一條通信線路來說,服務器端和客服端的角色是確定的。HTTP 協議規定,請求從客戶端發出,最后服務器端響應該請求并返回。換句話說,肯定是先從客戶端開始建立通信的,服務器端在沒有接收到請求之前不會發送響應。
7.2HTTP是不保存狀態的協議
HTTP 是一種無狀態協議。協議自身不對請求和響應之間的通信狀態進行保存。也就是說在 HTTP 這個級別,協議對于發送過的請求或響應都不做持久化處理。這是為了更快地處理大量事務,確保協議的可伸縮性,而特意把 HTTP 協議設計成如此簡單的。可是隨著 Web 的不斷發展,我們的很多業務都需要對通信狀態進行保存。于是我們引入了 Cookie 技術。有了 Cookie 再用 HTTP 協議通信,就可以管理狀態了。
?
7.3使用Cookie的狀態管理
Cookie 技術通過在請求和響應報文中寫入 Cookie 信息來控制客戶端的狀態。Cookie 會根據從服務器端發送的響應報文內的一個叫做 Set-Cookie 的首部字段信息,通知客戶端保存Cookie。當下次客戶端再往該服務器發送請求時,客戶端會自動在請求報文中加入 Cookie 值后發送出去。服務器端發現客戶端發送過來的 Cookie 后,會去檢查究竟是從哪一個客戶端發來的連接請求,然后對比服務器上的記錄,最后得到之前的狀態信息。
Cookie 的流程:
7.4 請求URI定位資源
HTTP 協議使用 URI 定位互聯網上的資源。正是因為 URI 的特定功能,在互聯網上任意位置的資源都能訪問到。
?
7.5 告知服務器意圖的 HTTP 方法(HTTP/1.1)
7.6 持久連接
HTTP 協議的初始版本中,每進行一個 HTTP 通信都要斷開一次 TCP 連接。比如使用瀏覽器瀏覽一個包含多張圖片的 HTML 頁面時,在發送請求訪問 HTML 頁面資源的同時,也會請求該 HTML 頁面里包含的其他資源。因此,每次的請求都會造成無畏的 TCP 連接建立和斷開,增加通信量的開銷。
為了解決上述 TCP 連接的問題,HTTP/1.1 和部分 HTTP/1.0 想出了持久連接的方法。其特點是,只要任意一端沒有明確提出斷開連接,則保持 TCP 連接狀態。旨在建立一次 TCP 連接后進行多次請求和響應的交互。在 HTTP/1.1 中,所有的連接默認都是持久連接。
?
7.7 管線化
持久連接使得多數請求以管線化方式發送成為可能。以前發送請求后需等待并接收到響應,才能發送下一個請求。管線化技術出現后,不用等待亦可發送下一個請求。這樣就能做到同時并行發送多個請求,而不需要一個接一個地等待響應了。
比如,當請求一個包含多張圖片的 HTML 頁面時,與挨個連接相比,用持久連接可以讓請求更快結束。而管線化技術要比持久連接速度更快。請求數越多,時間差就越明顯。
?
8、HTTP協議報文結構
8.1 HTTP報文
用于 HTTP 協議交互的信息被稱為 HTTP 報文。請求端(客戶端)的 HTTP 報文叫做請求報文;響應端(服務器端)的叫做響應報文。HTTP 報文本身是由多行(用 CR+LF 作換行符)數據構成的字符串文本。
?
8.2 HTTP報文結構
HTTP 報文大致可分為報文首部和報文主體兩部分。兩者由最初出現的空行(CR+LF)來劃分。通常,并不一定有報文主體。
HTTP 報文結構如下:
8.3 請求報文結構
請求報文的首部內容由以下數據組成:
- 請求行 —— 包含用于請求的方法、請求 URI 和 HTTP 版本;
- 首部字段 —— 包含表示請求的各種條件和屬性的各類首部。(通用首部、請求首部、實體首部以及RFC里未定義的首部如 Cookie 等)。
請求報文的示例,如下:
8.4 響應報文結構
響應報文的首部內容由以下數據組成:
- 狀態行 —— 包含表明響應結果的狀態碼、原因短語和 HTTP 版本;
- 首部字段 —— 包含表示請求的各種條件和屬性的各類首部。(通用首部、響應首部、實體首部以及RFC里未定義的首部如 Cookie 等)。
響應報文的示例,如下:
9、HTTP報文首部之首部字段(重點分析)
9.1 首部字段概述
先來回顧一下首部字段在報文的位置,HTTP 報文包含報文首部和報文主體,報文首部包含請求行(或狀態行)和首部字段。
在報文眾多的字段當中,HTTP 首部字段包含的信息最為豐富。首部字段同時存在于請求和響應報文內,并涵蓋 HTTP 報文相關的內容信息。使用首部字段是為了給客服端和服務器端提供報文主體大小、所使用的語言、認證信息等內容。
9.2 首部字段結構
HTTP 首部字段是由首部字段名和字段值構成的,中間用冒號“:”分隔。
另外,字段值對應單個 HTTP 首部字段可以有多個值。
當 HTTP 報文首部中出現了兩個或以上具有相同首部字段名的首部字段時,這種情況在規范內尚未明確,根據瀏覽器內部處理邏輯的不同,優先處理的順序可能不同,結果可能并不一致。
9.3 首部字段類型
首部字段根據實際用途被分為以下4種類型:
9.4 通用首部字段(HTTP/1.1)
9.5 請求首部字段(HTTP/1.1)
9.6 響應首部字段(HTTP/1.1)
9.7 實體首部字段(HTTP/1.1)
9.8 為Cookie服務的首部字段
?
10、其他首部字段
HTTP 首部字段是可以自行擴展的。所以在 Web 服務器和瀏覽器的應用上,會出現各種非標準的首部字段。以下是最為常用的首部字段。
X-Frame-Options:
X-Frame-Options: DENY 首部字段 X-Frame-Options 屬于 HTTP 響應首部,用于控制網站內容在其他 Web 網站的 Frame 標簽內的顯示問題。其主要目的是為了防止點擊劫持(clickjacking)攻擊。首部字段 X-Frame-Options 有以下兩個可指定的字段值:
- DENY:拒絕;
- SAMEORIGIN:僅同源域名下的頁面(Top-level-browsing-context)匹配時許可。(比如,當指定 http://sample.com/sample.html 頁面為 SAMEORIGIN 時,那么 sample.com 上所有頁面的 frame 都被允許可加載該頁面,而 example.com 等其他域名的頁面就不行了)。
X-XSS-Protection:
X-XSS-Protection: 1 首部字段 X-XSS-Protection 屬于 HTTP 響應首部,它是針對跨站腳本攻擊(XSS)的一種對策,用于控制瀏覽器 XSS 防護機制的開關。首部字段 X-XSS-Protection 可指定的字段值如下:
- 0 :將 XSS 過濾設置成無效狀態
- 1 :將 XSS 過濾設置成有效狀態
DNT:
DNT: 1 首部字段 DNT 屬于 HTTP 請求首部,其中 DNT 是 Do Not Track 的簡稱,意為拒絕個人信息被收集,是表示拒絕被精準廣告追蹤的一種方法。首部字段 DNT 可指定的字段值如下:
- 0 :同意被追蹤
- 1 :拒絕被追蹤
由于首部字段 DNT 的功能具備有效性,所以 Web 服務器需要對 DNT做對應的支持。
P3P:
P3P: CP="CAO DSP LAW CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa OUR BUS IND 首部字段 P3P 屬于 HTTP 響應首部,通過利用 P3P(The Platform for Privacy Preferences,在線隱私偏好平臺)技術,可以讓 Web 網站上的個人隱私變成一種僅供程序可理解的形式,以達到保護用戶隱私的目的。
要進行 P3P 的設定,需按以下操作步驟進行:
- 步驟 1:創建 P3P 隱私
- 步驟 2:創建 P3P 隱私對照文件后,保存命名在 /w3c/p3p.xml
- 步驟 3:從 P3P 隱私中新建 Compact policies 后,輸出到 HTTP 響應中
?
11、HTTP響應狀態碼
?
| 消息 | 描述 |
| 100 Continue | 服務器僅接收到部分請求,但是一旦服務器并沒有拒絕該請求,客戶端應該繼續發送其余的請求。 |
| 101 Switching Protocols | 服務器轉換協議:服務器將遵從客戶的請求轉換到另外一種協議。 |
| 消息 | 描述 |
| 200 OK | 請求成功(其后是對GET和POST請求的應答文檔。) |
| 201 Created | 請求被創建完成,同時新的資源被創建。 |
| 202 Accepted | 供處理的請求已被接受,但是處理未完成。 |
| 203 Non-authoritative Information | 文檔已經正常地返回,但一些應答頭可能不正確,因為使用的是文檔的拷貝。 |
| 204 No Content | 沒有新文檔。瀏覽器應該繼續顯示原來的文檔。如果用戶定期地刷新頁面,而Servlet可以確定用戶文檔足夠新,這個狀態代碼是很有用的。 |
| 205 Reset Content | 沒有新文檔。但瀏覽器應該重置它所顯示的內容。用來強制瀏覽器清除表單輸入內容。 |
| 206 Partial Content | 客戶發送了一個帶有Range頭的GET請求,服務器完成了它。 |
| 消息 | 描述 |
| 300 Multiple Choices | 多重選擇。鏈接列表。用戶可以選擇某鏈接到達目的地。最多允許五個地址。 |
| 301 Moved Permanently | 所請求的頁面已經轉移至新的url。 |
| 302 Found | 所請求的頁面已經臨時轉移至新的url。 |
| 303 See Other | 所請求的頁面可在別的url下被找到。 |
| 304 Not Modified | 未按預期修改文檔。客戶端有緩沖的文檔并發出了一個條件性的請求(一般是提供If-Modified-Since頭表示客戶只想比指定日期更新的文檔)。服務器告訴客戶,原來緩沖的文檔還可以繼續使用。 |
| 305 Use Proxy | 客戶請求的文檔應該通過Location頭所指明的代理服務器提取。 |
| 306 Unused | 此代碼被用于前一版本。目前已不再使用,但是代碼依然被保留。 |
| 307 Temporary Redirect | 被請求的頁面已經臨時移至新的url。 |
| 消息 | 描述 |
| 400 Bad Request | 服務器未能理解請求。 |
| 401 Unauthorized | 被請求的頁面需要用戶名和密碼。 |
| 401.1 | 登錄失敗。 |
| 401.2 | 服務器配置導致登錄失敗。 |
| 401.3 | 由于 ACL 對資源的限制而未獲得授權。 |
| 401.4 | 篩選器授權失敗。 |
| 401.5 | ISAPI/CGI 應用程序授權失敗。 |
| 401.7 | 訪問被 Web 服務器上的 URL 授權策略拒絕。這個錯誤代碼為 IIS 6.0 所專用。 |
| 402 Payment Required | 此代碼尚無法使用。 |
| 403 Forbidden | 對被請求頁面的訪問被禁止。 |
| 403.1 | 執行訪問被禁止。 |
| 403.2 | 讀訪問被禁止。 |
| 403.3 | 寫訪問被禁止。 |
| 403.4 | 要求 SSL。 |
| 403.5 | 要求 SSL 128。 |
| 403.6 | IP 地址被拒絕。 |
| 403.7 | 要求客戶端證書。 |
| 403.8 | 站點訪問被拒絕。 |
| 403.9 | 用戶數過多。 |
| 403.10 | 配置無效。 |
| 403.11 | 密碼更改。 |
| 403.12 | 拒絕訪問映射表。 |
| 403.13 | 客戶端證書被吊銷。 |
| 403.14 | 拒絕目錄列表。 |
| 403.15 | 超出客戶端訪問許可。 |
| 403.16 | 客戶端證書不受信任或無效。 |
| 403.17 | 客戶端證書已過期或尚未生效。 |
| 403.18 | 在當前的應用程序池中不能執行所請求的 URL。這個錯誤代碼為 IIS 6.0 所專用。 |
| 403.19 | 不能為這個應用程序池中的客戶端執行 CGI。這個錯誤代碼為 IIS 6.0 所專用。 |
| 403.20 | Passport 登錄失敗。這個錯誤代碼為 IIS 6.0 所專用。 |
| 404 Not Found | 服務器無法找到被請求的頁面。 |
| 404.0 | (無)–沒有找到文件或目錄。 |
| 404.1 | 無法在所請求的端口上訪問 Web 站點。 |
| 404.2 | Web 服務擴展鎖定策略阻止本請求。 |
| 404.3 | MIME 映射策略阻止本請求。 |
| 405 Method Not Allowed | 請求中指定的方法不被允許。 |
| 406 Not Acceptable | 服務器生成的響應無法被客戶端所接受。 |
| 407 Proxy Authentication Required | 用戶必須首先使用代理服務器進行驗證,這樣請求才會被處理。 |
| 408 Request Timeout | 請求超出了服務器的等待時間。 |
| 409 Conflict | 由于沖突,請求無法被完成。 |
| 410 Gone | 被請求的頁面不可用。 |
| 411 Length Required | "Content-Length" 未被定義。如果無此內容,服務器不會接受請求。 |
| 412 Precondition Failed | 請求中的前提條件被服務器評估為失敗。 |
| 413 Request Entity Too Large | 由于所請求的實體的太大,服務器不會接受請求。 |
| 414 Request-url Too Long | 由于url太長,服務器不會接受請求。當post請求被轉換為帶有很長的查詢信息的get請求時,就會發生這種情況。 |
| 415 Unsupported Media Type | 由于媒介類型不被支持,服務器不會接受請求。 |
| 416 Requested Range Not Satisfiable | 服務器不能滿足客戶在請求中指定的Range頭。 |
| 417 Expectation Failed | 執行失敗。 |
| 423 | 鎖定的錯誤。 |
| 消息 | 描述 |
| 500 Internal Server Error | 請求未完成。服務器遇到不可預知的情況。 |
| 500.12 | 應用程序正忙于在 Web 服務器上重新啟動。 |
| 500.13 | Web 服務器太忙。 |
| 500.15 | 不允許直接請求 Global.asa。 |
| 500.16 | UNC 授權憑據不正確。這個錯誤代碼為 IIS 6.0 所專用。 |
| 500.18 | URL 授權存儲不能打開。這個錯誤代碼為 IIS 6.0 所專用。 |
| 500.100 | 內部 ASP 錯誤。 |
| 501 Not Implemented | 請求未完成。服務器不支持所請求的功能。 |
| 502 Bad Gateway | 請求未完成。服務器從上游服務器收到一個無效的響應。 |
| 502.1 | CGI 應用程序超時。 · |
| 502.2 | CGI 應用程序出錯。 |
| 503 Service Unavailable | 請求未完成。服務器臨時過載或當機。 |
| 504 Gateway Timeout | 網關超時。 |
| 505 HTTP Version Not Supported | 服務器不支持請求中指明的HTTP協議版本。 |
?
12、HTTP報文實體
12.1 HTTP報文實體概述
大家請仔細看看上面示例中,各個組成部分對應的內容。
接著,我們來看看報文和實體的概念。如果把 HTTP 報文想象成因特網貨運系統中的箱子,那么 HTTP 實體就是報文中實際的貨物。
- 報文:是網絡中交換和傳輸的數據單元,即站點一次性要發送的數據塊。報文包含了將要發送的完整的數據信息,其長短很不一致,長度不限且可變;
- 實體:作為請求或響應的有效載荷數據(補充項)被傳輸,其內容由實體首部和實體主體組成。(實體首部相關內容在上面第六點中已有闡述。)
我們可以看到,上面示例右圖中深紅色框的內容就是報文的實體部分,而藍色框的兩部分內容分別就是實體首部和實體主體。而左圖中粉紅框內容就是報文主體。
通常,報文主體等于實體主體。只有當傳輸中進行編碼操作時,實體主體的內容發生變化,才導致它和報文主體產生差異。
?
12.2 內容編碼
HTTP 應用程序有時在發送之前需要對內容進行編碼。例如,在把很大的 HTML 文檔發送給通過慢速連接上來的客戶端之前,服務器可能會對其進行壓縮,這樣有助于減少傳輸實體的時間。服務器還可以把內容攪亂或加密,以此來防止未授權的第三方看到文檔的內容。
這種類型的編碼是在發送方應用到內容之上的。當內容經過內容編碼后,編好碼的數據就放在實體主體中,像往常一樣發送給接收方。
內容編碼類型:
12.3 傳輸編碼
內容編碼是對報文的主體進行的可逆變換,是和內容的具體格式細節緊密相關的。
傳輸編碼也是作用在實體主體上的可逆變換,但使用它們是由于架構方面的原因,同內容的格式無關。使用傳輸編碼是為了改變報文中的數據在網絡上傳輸的方式。
12.4 分塊編碼
分塊編碼把報文分割成若干已知大小的塊。塊之間是緊挨著發送的,這樣就不需要在發送之前知道整個報文的大小了。分塊編碼是一種傳輸編碼,是報文的屬性。
若客戶端與服務器端之間不是持久連接,客戶端就不需要知道它在讀取的主體的長度,而只需要讀取到服務器關閉主體連接為止。
當使用持久連接時,在服務器寫主體之前,必須知道它的大小并在 Content-Length 首部中發送。如果服務器動態創建內容,就可能在發送之前無法知道主體的長度。
分塊編碼為這種困難提供了解決方案,只要允許服務器把主體分塊發送,說明每塊的大小就可以了。因為主體是動態創建的,服務器可以緩沖它的一部分,發送其大小和相應的塊,然后在主體發送完之前重復這個過程。服務器可以用大小為 0 的塊作為主體結束的信號,這樣就可以繼續保持連接,為下一個響應做準備。
來看看一個分塊編碼的報文示例:
12.5 多部分媒體類型
MIME 中的 multipart(多部分)電子郵件報文中包含多個報文,它們合在一起作為單一的復雜報文發送。每一部分都是獨立的,有各自的描述其內容的集,不同部分之間用分界字符串連接在一起。
相應得,HTTP 協議中也采納了多部分對象集合,發送的一份報文主體內可包含多種類型實體。
多部分對象集合包含的對象如下:
- multipart/form-data:在 Web 表單文件上傳時使用;
- multipart/byteranges:狀態碼 206 Partial Content 響應報文包含了多個范圍的內容時使用。
?
12.6 范圍請求
假設你正在下載一個很大的文件,已經下了四分之三,忽然網絡中斷了,那下載就必須重頭再來一遍。為了解決這個問題,需要一種可恢復的機制,即能從之前下載中斷處恢復下載。要實現該功能,這就要用到范圍請求。
有了范圍請求, HTTP 客戶端可以通過請求曾獲取失敗的實體的一個范圍(或者說一部分),來恢復下載該實體。當然這有一個前提,那就是從客戶端上一次請求該實體到這一次發出范圍請求的時間段內,該對象沒有改變過。例如:
上面示例中,客戶端請求的是文檔開頭20224字節之后的部分。
?
13、與HTTP協作的Web服務器
HTTP 通信時,除客戶端和服務器外,還有一些用于協助通信的應用程序。如下列出比較重要的幾個:代理、緩存、網關、隧道、Agent 代理。
?
13.1 代理
HTTP 代理服務器是 Web 安全、應用集成以及性能優化的重要組成模塊。代理位于客戶端和服務器端之間,接收客戶端所有的 HTTP 請求,并將這些請求轉發給服務器(可能會對請求進行修改之后再進行轉發)。對用戶來說,這些應用程序就是一個代理,代表用戶訪問服務器。
出于安全考慮,通常會將代理作為轉發所有 Web 流量的可信任中間節點使用。代理還可以對請求和響應進行過濾,安全上網或綠色上網。
?
13.2 緩存
瀏覽器第一次請求:
瀏覽器再次請求:
?
Web 緩存或代理緩存是一種特殊的 HTTP 代理服務器,可以將經過代理傳輸的常用文檔復制保存起來。下一個請求同一文檔的客戶端就可以享受緩存的私有副本所提供的服務了。客戶端從附近的緩存下載文檔會比從遠程 Web 服務器下載快得多。
?
13.3 網關
網關是一種特殊的服務器,作為其他服務器的中間實體使用。通常用于將 HTTP 流量轉換成其他的協議。網關接收請求時就好像自己是資源的源服務器一樣。客戶端可能并不知道自己正在跟一個網關進行通信。
?
13.4 隧道
隧道是會在建立起來之后,就會在兩條連接之間對原始數據進行盲轉發的 HTTP 應用程序。HTTP 隧道通常用來在一條或多條 HTTP 連接上轉發非 HTTP 數據,轉發時不會窺探數據。
HTTP 隧道的一種常見用途就是通過 HTTP 連接承載加密的安全套接字層(SSL)流量,這樣 SSL 流量就可以穿過只允許 Web 流量通過的防火墻了。
?
13.5 Agent代理
Agent 代理是代表用戶發起 HTTP 請求的客戶端應用程序。所有發布 Web 請求的應用程序都是 HTTP Agent 代理。
(原文鏈接:https://www.jianshu.com/p/6e9e4156ece3)
總結
以上是生活随笔為你收集整理的网络编程懒人入门(七):深入浅出,全面理解HTTP协议的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 生成正弦波声音_Java错误生
- 下一篇: 对pgm格式图片的批量格式转换(pgm)