Android 網絡基礎 -- HTTP 請求過程及理解

本文來自 圖解 HTTP ,相關資料與圖片均來自於該書

HTTP 通信過程中,從客戶端到服務端的響應是怎麼樣的呢?這一章,我們一起來了解一下。

一、HTTP 報文

用於 HTTP 協議交互的信息被稱爲 HTTP 報文。 客戶端的報文叫做請求報文,服務端的則叫響應報文。

HTTP 報文大致可分爲報文首部報文主體兩塊。由換行符來區分,通常,並不一定有報文主體,如下圖所示:
在這裏插入圖片描述
請求報文 和 響應報文 的結構,大致可以分爲
請求(響應)行 - 狀態行 - 報文主體:
在這裏插入圖片描述

  • 請求行 :包含用於請求的方法,請求 URI 和 HTTP 版本
  • 狀態行 :包含表明影響結果的狀態碼,原因短語和 HTTP 版本
  • 首部字段 :表示請求和響應的各種條件和屬性的各類首部,一般有4種,分別是:通過首部,請求首部,響應首部和實體首部。

一個實例如下:
在這裏插入圖片描述

1.1 報文主體和實體主體的差異

  • 報文
    是HTTP通信中的基本單位,由 8 個字節流組成。
  • 實體
    作爲請求或響應的有效載荷數據(補充項)被傳輸,其內容由實體首部和實體主體組成。

怎麼理解呢?先理解,主體是報文的一部分,如下面一段響應報文:

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 5
Zhihu

其中除了報文首部字段,實體其實就是 “Zhihu”,報文主體其實等於實體主體,但它並沒有實體首部,只有實體主體,但如果是一個表單,則實體首部和實體主體就有了,如下:

POST /upload HTTP/1.1
Host: example.com
Content-Length: xxx
Content-Type: multipart/form-data; boundary=AaBbCcDd

--AaBbCcDd
Content-Disposition: form-data; name="username"

RuphiLau
--AaBbCcDd
Content-Disposition: form-data; name="file"; filename="picture.jpg"
Content-Type: image/jpeg

...(picture.jpg的數據)...
--AaBbCcDd--

1.2 壓縮傳輸的內容編碼

爲了便於傳輸,通常會對原始內容進行原樣壓縮,再由接收端接收和解碼,常用的內容編碼有以下幾種:

  • gzip (GNU zip)
  • compress (UNIX 系統的標準壓縮)
  • deflaate (zip)
  • identity (不進行壓縮)

1.3 分塊傳輸編碼

通常,如果實體內容過大,在未傳輸完成之前,瀏覽器無法實現請求頁面;所以在傳輸大容量數據時,會把數據分割成多塊,讓瀏覽器逐步顯示頁面。
這種把主體分塊的功能被稱爲 - 分塊傳輸編碼
分塊傳輸編碼,會把實體主體分成很多塊,每一塊都會特殊的十六進制來標記大小,而最後一塊,則是使用 "0(CT_LF)"來標記。

這樣,客戶端在接收的時候,先檢測到頭部的大小信息,當接收的大小與頭部信息吻合時,就說明這個塊接收完成了,當所有的塊接收完成時,整個實體信息也就接收完成了。
這種思想,也常常用在 socket 傳輸的粘包粘包的處理上。

1.4 發送多種數據對象

當 HTTP 想發送多種類型的數據時,該怎麼處理呢?

這裏可以借鑑郵件發送,郵件發送可以發送文字、視頻、圖片等附件;這裏因爲採用了 MIME(多部分對象) 機制。它允許郵件處理文本、圖片、視頻等多個不同類型的數據。

響應的,HTTP 也採用了這一機制,發送的報文主體內可含多種類型實體。通常是在圖片或 文本上傳時使用。
對象集合包含的如下:

  • mulripart/form-data : 在 Web 表單文件上傳時使用
  • mulpart/byteranges : 狀態碼 206 (部分內容),響應報文包含多個範圍的內容時使用,比如 Range 屬性。

當要使用多部分對象時,需要在首部字段里加上 Content-type。關於這些字段,咱們後面再講。

1.5 獲取部門內容

當我們要獲取一個大文件時,爲了防止網絡中斷的情況,從而從頭開始下的問題。就需要一個可恢復的機制,即從之前的下載中斷處恢復下載。

要實現該功能需要指定下載的實體 範圍,這個請求範圍,可以使用 Range 的頭部信息來指定,格式如下:

  • 5001 ~ 10000 個字節 : Range: bytes=5001-10000
  • 從 5001 之後的全部:Range:bytes=5001 -
  • 從開始到3000字節,和 5000 到 7000 字節的多種範圍

注意,當針對請求範圍時,返回的狀態碼爲 206 的響應報文,如果服務器不支持,則返回 200 和全部實體。
在這裏插入圖片描述

1.6 內容協商

同一份 Web 請求,可能返回的多份相同內容的頁面,比如英文版和中文版的 Web 頁面。儘管內容相同,但是語言卻是不同的。

當客戶端和服務端就響應的資源內容進行交涉,然後提供給客戶端最合適的資源,這種機制,叫做內容協商。

內容協商會以響應資源的語言、字符集、編碼方式等作爲判斷依據。包含在請求報文中的某些首部字段,如:

  • Accept
  • Accept-Charset
  • Accept-Encoding
  • Accept-Language
  • Content-Language

關於首部字段,後面再講。

二、HTTP 狀態碼

狀態碼的職責是當客戶端向服務端發起請求時,描述返回的請求結果。根據狀態碼,就可以知道服務端是正常處理了請求,還是出現了錯誤。
狀態碼 如 200 OK ,以 3 位數字和原因短語組成。
類別如下:
在這裏插入圖片描述
狀態碼的數量非常多,但我們只需要記住14個常用的就可以了:

2xx的響應結果表示請求被正常處理了

  • 200 :OK 服務端正常處理了請求
  • 204 :NO Content,正常處理,但沒有資源可返回;即報文中,沒有實體部分。一般當客戶端只向服務端發送消息而不需要更新什麼的情況下使用。
  • 206 :範圍請求 ,一般用於 Content-Range 指定範圍的請求。

3xx 響應結果表示瀏覽器需要執行某些特殊的處理,才能正確處理請求
關於3xx的詳細解釋,可以參考這篇文章 https://www.cnblogs.com/wuguanglin/p/redirect.html

  • 301 : 永久性重定向,表示客戶端請求的資源已經被分配了新的URI ,即請求的 URI 被定爲到新的地址,此時服務器會返回新的地址,客戶端重新訪問這個新地址即可。這是應該按 Location 首部字段提示的 URI 重新保存。
    在這裏插入圖片描述
  • 302 :臨時重定向。該狀態碼錶示該資源已經被分配了新的 URI ,希望本次能使用新的 URI 訪問。
  • 303 : 表示請求的資源存在另一個 URI,應使用 GET 方法定向獲取請求的資源。

當 301,302,303 狀態碼返回時,幾乎所有的瀏覽器都會把 POST 改成 GET ,並刪除請求報文內的主體,之後請求會自動再次發送。
301,302,是禁止把 POST 改成 GET 的,但實際大家都會這麼 做。

  • 304 : 表示當客戶端發送附帶條件的請求時,服務器允許響應,但是請求條件未滿足時,直接返回304.
  • 307 : 臨時重定向。與 302 有關係,但是 302 不允許把 POST 改成 GET ,實際大家都會這麼做;但 307 則不會把 POST 改成 GET ,而是遵照瀏覽器標準,根據可能出現不同的結果。

4xx 的響應結果表示客戶端是發生錯誤的原因所在。

  • 400:Bad Request,客戶端的請求報文中存在錯誤。
  • 401:Unauthorized,表示請求需要通過 HTTP 認證,若之前已進行 1 次請求,則表示用戶認證失敗。
  • 403:Forbidden,訪問的資源被服務器拒絕了。
  • 404:Not found,服務器沒有該資源。

5xx 表示服務器本身發啊生錯誤無。

  • 500:Internal Server Error,表示服務器執行請求時,發生了錯誤,也可能是 Web 的問題。
  • 503:Service Unavailable,服務器暫時處於超負載或正在進行停機維護,現在無法處理請求。

三、與HTTP協作的服務器

3.1 單臺主體實現多個域名

HTTP 允許一臺 HTTP 服務器搭建多個 Web 站點,比如,一個服務器,有多個域名,www.ssgodie.win 和 www.ggdie.win 都可以指向同一個服務器,因爲它們指向的ip都是指向這臺服務器的。

3.2 代理

代理服務器英文全稱是Proxy Server,其功能就是代理網絡用戶去取得網絡信息。形象的說:它是網絡信息的中轉站。

在一般情況下,我們使用網絡瀏覽器直接去連接其他Internet站點取得網絡信息時,須送Request信號來得到回答,然後對方再把信息以bit方式傳送回來。
代理服務器是介於瀏覽器和Web服務器之間的一臺服務器,有了它之後,瀏覽器不是直接到Web服務器去取回網頁而是向代理服務器發出請求,Request信號會先送到代理服務器,由代理服務器來取回瀏覽器所需要的信息並傳送給你的瀏覽器。
而且,大部分代理服務器都具有緩衝的功能,就好象一個大的Cache,它有很大的存儲空間,它不斷將新取得數據儲存到它本機的存儲器上,如果瀏覽器所請求的數據在它本機的存儲器上已經存在而且是最新的,那麼它就不重新從Web服務器取數據,而直接將存儲器上的數據傳送給用戶的瀏覽器,這樣就能顯著提高瀏覽速度和效率。更重要的是:Proxy Server(代理服務器)是Internet鏈路級網關所提供的一種重要的安全功能。

3.3 網關

從一個房間去另一個房間,必須經過一扇門,同樣,從一個網絡訪問另一個網絡,也需要 “關口”,
這就是網關。在這裏插入圖片描述
那麼網關到底是什麼呢?網關實質上是一個網絡通向其他網絡的IP地址。
比如有網絡A和網絡B,
網絡A的IP地址範圍爲“192.168.1.1~192. 168.1.254”,子網掩碼爲255.255.255.0;
網絡B的IP地址範圍爲“192.168.2.1~192.168.2.254”,子網掩碼爲255.255.255.0。

在沒有路由器的情況下,兩個網絡之間是不能進行TCP/IP通信的,即使是兩個網絡連接在同一臺交換機(或集線器)上,TCP/IP協議也會根據子網掩碼(255.255.255.0)判定兩個網絡中的主機處在不同的網絡裏。

而要實現這兩個網絡之間的通信,則必須通過網關。如果網絡A中的主機發現數據包的目的主機不在本地網絡中,就把數據包轉發給它自己的網關,再由網關轉發給網絡B的網關,網絡B的網關再轉發給網絡B的某個主機。網絡A向網絡B轉發數據包的過程。

所以說,只有設置好網關的IP地址,TCP/IP協議才能實現不同網絡之間的相互通信。

那麼這個IP地址是哪臺機器的IP地址呢?

網關的IP地址是具有路由功能的設備的IP地址,具有路由功能的設備有路由器、啓用了路由協議的服務器(實質上相當於一臺路由器)、代理服務器(也相當於一臺路由器)。

3.3 隧道

網絡隧道是一個特殊的網絡協議,它利用一種網絡協議來傳輸另一種網絡協議,它主要利用網絡隧道協議來實現這種功能。屆時使用 SSL 等加密手段啊進行通信。
隧道本身不會去解析HTTP請求,也就是說,請求保持原樣中轉給之後的服務器,隧道會在通信雙方斷開連接時結束。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章