1. 程式人生 > 實用技巧 >【網路】圖解HTTP-1

【網路】圖解HTTP-1

書籍是人類進步的階梯--高爾基

前言

今天介紹一個簡單的話題,你知道當我們在瀏覽器網頁位址列輸入URL時,Web頁面是如何呈現的嗎?

當然Web頁面不可能憑空顯示出來,簡單來說是Web瀏覽器根據我們輸入的URL地址,向Web伺服器獲取檔案資源然後顯示在瀏覽器上,但是背後其實有這一個非常複雜的過程。像這種通過傳送請求獲取伺服器資源的 Web 瀏覽器等, 都可稱為客戶端( client) 。

而客戶端和Web伺服器端之間通訊是使用一種名為 HTTP( HyperText Transfer Protocol, 超文字傳輸協 議) 的協議作為規範, 只有雙方遵循這種規範二者才能通訊。比如:兩個人說話都用普通話肯定都能聽懂,假如其中一個用方言或者都用各自的方言是不是兩個人談話都比較難懂,甚至有的方言根本聽不懂。那麼下面就來說說HTTP

與 HTTP 關係密切的協議

為了理解 HTTP, 我們有必要事先了解一下 TCP/IP 協議族。TCP/IP 是網際網路相關的各類協議族的總稱,HTTP協議就是其中的一個子集。而這些協議是計算機與網路裝置要相互通訊的規則,想要通訊雙方就必須基於相同的方法。

TCP/IP 的分層管理

TCP/IP 協議族裡重要的一點就是分層。 TCP/IP 協議族按層次分別分為以下 4 層: 應用層、 傳輸層、 網路層和資料鏈路層。分層的好處就是使得每一層之間都是低耦合,如果某個地方改動只需要改變特定層級的協議,而不必把整體全部換掉,下面的一副圖展示了每層的作用:

另外擴充套件一幅圖,上圖是通過TCP/IP的四層模型劃分,下面一幅圖是通過OSI

的七層模型劃分,可以瞭解一下,很有用:

TCP/IP 通訊傳輸流

現在我們瞭解到了TCP/IP協議族的四層模型,我們可以看到HTTP是屬於應用層,也就是說當我們在瀏覽器上面訪問一個網站,利用 TCP/IP 協議族進行網路通訊時, 會通過分層順序與對方進行通訊。 傳送端從應用層往下走, 接收端則往應用層往上走,具體過程如下圖:

負責傳輸的 IP 協議

IP 協議的作用是把各種資料包傳送給對方。 而要保證確實傳送到對方那裡, 則需要滿足各類條件。 其中兩個重要的條件是 IP 地址和 MAC地址

IP 地址指明瞭節點被分配到的地址, MAC 地址是指網絡卡所屬的固定地址。而IP 間的通訊依賴 MAC 地址。但是往往通訊的雙方不在同一個區域網,例如:我們搜尋百度,百度肯定不和我們在一個區域網,就需要經過多臺計算機和網路裝置中轉才能連線到百度。 而在進行中轉時, 會利用下一站中轉裝置的 MAC地址來搜尋下一個中轉目標。 這時, 會採用 ARP 協議( AddressResolution Protocol)

ARP 是一種用以解析地址的協議, 根據通訊方的 IP 地址就可以反查出對應的 MAC 地址。

確保可靠性的 TCP 協議

按層次分, TCP 位於傳輸層, 提供可靠的位元組流服務。位元組流服務為了方便傳輸, 將大塊資料分割成以報文段( segment) 為單位的資料包進行管理。 而且 TCP 協議能夠確認資料最終是否送達到對方,保證傳輸可靠性。而這種可靠性就是TCP 協議採用了三次握手( three-way handshaking) 策略,意思就是用 TCP 協議把資料包送出去後,一定會向對方確認是否成功送達,過程如圖所示:

第一次握手:客戶端主動傳送帶有SYN標識的請求,然後處於SYNC_SENT狀態,等待伺服器確認。(此時客戶端不知道伺服器接受到了自己傳送的請求沒有)

第二次握手:伺服器接受到客戶端傳送過來的SYN並且需要傳送ACK資訊對這個SYN報文段進行確認,同時還要傳送自己的SYN請求資訊,服務端會把ACK+SYN放在一個報文段傳送給客戶端,此時處於SYN_RECEIVED狀態。(此時伺服器端知道客戶端有傳送的功能,但是不知道自己有沒有傳送的功能以及客戶端有沒有接受的功能

第三次握手:客戶端接受到服務端的SYN+ACK(此時客戶端知道自己有傳送的功能以及伺服器的接受功能,但是伺服器還不知道自己的接受功能),接著客戶端會向服務端傳送ACK的確認標識,傳送完畢後雙方進入Established,(此時伺服器端接受到ACK,知道了客戶端的接受功能)完成TCP三次握手。

過程梳理:

1.客戶端傳送請求連線SYN

2.服務端回覆確認ACK,併發送自己的SYN(此步驟完成客戶端知道自己有傳送能力和接受能力,以及伺服器端的傳送和接受能力。但是服務端只知道客戶端傳送能力)

3.客戶端恢復ACK(此步驟完成服務端知道客戶端接受能力)

4.以上步驟完成,客戶端和服務端均知道對方的接受和傳送能力,即三次握手完畢

負責域名解析的 DNS 服務

DNS( Domain Name System) 服務是和 HTTP 協議一樣位於應用層的協議。 它提供域名到 IP 地址之間的解析服務。

還是上述的例子,當我們訪問百度的時候是直接通過在瀏覽器的位址列輸入www.baidu.com而非輸入的是IP地址,但是在網路連線過程中,真正傳輸的是IP地址,而非www.baidu.com,實則www.baidu.com是域名,該域名的背後實則就是IP地址,而我們並沒有輸入IP地址,那麼傳輸是如何進行的?此時就需要用到DNS服務,而DNS 協議就可以提供通過域名查詢 IP 地址, 或逆向從 IP 地址反查域名的服務。也就是說我們的輸入www.baidu.com連線訪問是先通過DNS找到對應的IP地址,然後通過IP地址進行請求連線。大致過程如下圖:

各種協議與 HTTP 協議的關係

通過下圖瞭解下 IP 協議、 TCP 協議和 DNS 服務在使用HTTP 協議的通訊過程中各自發揮了哪些作用。

URI 和 URL

  • URI(Uniform Resource Identifier ):統一資源識別符號,URI 用字串標識某一網際網路資源,比如:

    • ftp://ftp.is.co.za/rfc/rfc1808.txt
    • http://www.ietf.org/rfc/rfc2396.txt
  • URL( Uniform Resource Locator):統一資源定位符,URL 表示資源的地點,比如:

    • http://www.baidi.com/

HTTP協議

超文字傳輸協議(HyperText Transfer Protocol,簡稱:HTTP)是一種通訊協議,它允許將超文字標記語言(HTML)文件從Web伺服器傳送到客戶端的瀏覽器,HTTP 協議規定, 請求從客戶端發出, 最後伺服器端響應該請求並返回。 換句話說, 肯定是先從客戶端開始建立通訊的, 伺服器端在沒有接收到請求之前不會發送響應。下面是一個具體示例:

下面則是從客戶端傳送給某個 HTTP 伺服器端的請求報文中以及響應報文的內容。

  • 請求報文是由請求方法、 請求 URI、 協議版本、 可選的請求首部欄位和內容實體構成的。
  • 響應報文由協議版本、 狀態碼( 表示請求成功或失敗的數字程式碼) 、 用以解釋狀態碼的原因短語、 可選的響應首部欄位以及實體主體構成。

常用請求HTTP請求方法

請求方法 介紹
GET 請求獲取指定的資源經伺服器端解析後返回響應內容
POST 用來傳輸實體的主體
PUT 用來傳輸檔案,要求在請求報文的主體中包含檔案內容, 然後儲存到請求 URI 指定的位置
HEAD 獲得報文首部,和 GET 方法一樣,但是不返回報文主體部分
DELETE 按請求 URI 刪除指定的資源
OPTIONS 用來查詢針對請求 URI 指定的資源支援的方法
TRACE 追蹤路徑
CONNECT 要求在與代理伺服器通訊時建立隧道, 實現用隧道協議進行 TCP 通訊。 主要使用 SSL( Secure Sockets Layer, 安全套接層) 和 TLS( Transport Layer Security, 傳輸層安全) 協議把通訊內容加 密後經網路隧道傳輸

持久連線

下圖是一個客戶端訪問服務端的多次請求示意圖:

圖中可以看出,客戶端每次訪問一個資源都需要進行TCP連線和斷開連線。而為解決TCP 連線的問題,也就是每次傳送一個請求就需要三次握手和四次揮手,於是 HTTP/1.1 和一部分的 HTTP/1.0 想出了持久連線( HTTP Persistent Connections, 也稱為 HTTP keep-alive 或HTTP connection reuse) 的方法。 持久連線的特點是隻要任意一端沒有明確提出斷開連線, 則保持 TCP 連線狀態

持久連線的好處在於減少了 TCP 連線的重複建立和斷開所造成的額外開銷, 減輕了伺服器端的負載。 另外, 減少開銷的那部分時間, 使HTTP 請求和響應能夠更早地結束。在 HTTP/1.1 中, 所有的連線預設都是持久連線,

HTTP 是無狀態協議, 它不對之前發生過的請求和響應的狀態進行管理。 也就是說, 無法根據之前的狀態進行本次的請求處理。

假設要求登入認證的 Web 頁面本身無法進行狀態的管理( 不記錄已登入的狀態) , 那麼每次跳轉新頁面要再次登入, 或者在每次請求報文中附加引數來管理登入狀態。

如果每次登入就很不現實,頁面折磨多,登入能把人累死。於是引入了 Cookie 技術。 Cookie 技術通過在請求和響應報文中寫入 Cookie 資訊來控制客戶端的狀態。

Cookie 會根據從伺服器端傳送的響應報文內的一個叫做 Set-Cookie 的首部欄位資訊, 通知客戶端儲存 Cookie。 當下次客戶端再往該伺服器傳送請求時, 客戶端會自動在請求報文中加入 Cookie 值後傳送出去。

伺服器端發現客戶端傳送過來的 Cookie 後, 會去檢查究竟是從哪一個客戶端發來的連線請求, 然後對比伺服器上的記錄, 最後得到之前的狀態資訊

上圖展示了發生 Cookie 互動的情景, HTTP 請求報文和響應報文的內容如下。

1.請求報文( 沒有 Cookie 資訊的狀態)

GET /reader/ HTTP/1.1
Host: hackr.jp
*首部欄位內沒有Cookie的相關資訊

2.響應報文( 伺服器端生成 Cookie 資訊)

HTTP/1.1 200 OK
Date: Thu, 12 Jul 2012 07:12:20 GMT
Server: Apache
Set-Cookie: sid=1342077140226724; path=/; expires=Wed,10-Oct-12 07:12:20 GMT
Content-Type: text/plain; charset=UTF-8

3.請求報文( 自動傳送儲存著的 Cookie 資訊)

GET /image/ HTTP/1.1
Host: hackr.jp
Cookie: sid=1342077140226724

相關參考:
圖解HTTP