1. 程式人生 > >詳解Http協議(一)

詳解Http協議(一)

一張圖帶你看完本篇文章

一、概述

1.計算機網路體系結構分層

計算機網路體系結構分層

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伺服器上站點的網頁程式碼提取出來,並翻譯成漂亮的網頁。

二、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 連線在傳送後將仍然保持開啟狀態,於是,客戶端可以繼續通過相同的連線傳送請求。保持連線節省了為每個請求建立新連線所需的時間,還節約了網路頻寬。

三、HTTP 協議基礎

1.通過請求和響應的交換達成通訊

應用 HTTP 協議時,必定是一端擔任客戶端角色,另一端擔任伺服器端角色。僅從一條通訊線路來說,伺服器端和客服端的角色是確定的。HTTP 協議規定,請求從客戶端發出,最後伺服器端響應該請求並返回。換句話說,肯定是先從客戶端開始建立通訊的,伺服器端在沒有接收到請求之前不會發送響應。

2.HTTP 是不儲存狀態的協議

HTTP 是一種無狀態協議。協議自身不對請求和響應之間的通訊狀態進行儲存。也就是說在 HTTP 這個級別,協議對於傳送過的請求或響應都不做持久化處理。這是為了更快地處理大量事務,確保協議的可伸縮性,而特意把 HTTP 協議設計成如此簡單的。 可是隨著 Web 的不斷髮展,我們的很多業務都需要對通訊狀態進行儲存。於是我們引入了 Cookie 技術。有了 Cookie 再用 HTTP 協議通訊,就可以管理狀態了。

3.使用 Cookie 的狀態管理

Cookie 技術通過在請求和響應報文中寫入 Cookie 資訊來控制客戶端的狀態。Cookie 會根據從伺服器端傳送的響應報文內的一個叫做 Set-Cookie 的首部欄位資訊,通知客戶端儲存Cookie。當下次客戶端再往該伺服器傳送請求時,客戶端會自動在請求報文中加入 Cookie 值後傳送出去。伺服器端發現客戶端傳送過來的 Cookie 後,會去檢查究竟是從哪一個客戶端發來的連線請求,然後對比伺服器上的記錄,最後得到之前的狀態資訊。

Cookie 的流程

4.請求 URI 定位資源

HTTP 協議使用 URI 定位網際網路上的資源。正是因為 URI 的特定功能,在網際網路上任意位置的資源都能訪問到。

5.告知伺服器意圖的 HTTP 方法(HTTP/1.1)

HTTP 方法

6.持久連線

HTTP 協議的初始版本中,每進行一個 HTTP 通訊都要斷開一次 TCP 連線。比如使用瀏覽器瀏覽一個包含多張圖片的 HTML 頁面時,在傳送請求訪問 HTML 頁面資源的同時,也會請求該 HTML 頁面裡包含的其他資源。因此,每次的請求都會造成無畏的 TCP 連線建立和斷開,增加通訊量的開銷。 為了解決上述 TCP 連線的問題,HTTP/1.1 和部分 HTTP/1.0 想出了持久連線的方法。其特點是,只要任意一端沒有明確提出斷開連線,則保持 TCP 連線狀態。旨在建立一次 TCP 連線後進行多次請求和響應的互動。在 HTTP/1.1 中,所有的連線預設都是持久連線。

7.管線化

持久連線使得多數請求以管線化方式傳送成為可能。以前傳送請求後需等待並接收到響應,才能傳送下一個請求。管線化技術出現後,不用等待亦可傳送下一個請求。這樣就能做到同時並行傳送多個請求,而不需要一個接一個地等待響應了。 比如,當請求一個包含多張圖片的 HTML 頁面時,與挨個連線相比,用持久連線可以讓請求更快結束。而管線化技術要比持久連線速度更快。請求數越多,時間差就越明顯。

四、HTTP 協議報文結構

1.HTTP 報文

用於 HTTP 協議互動的資訊被稱為 HTTP 報文。請求端(客戶端)的 HTTP 報文叫做請求報文;響應端(伺服器端)的叫做響應報文。HTTP 報文字身是由多行(用 CR+LF 作換行符)資料構成的字串文字。

2.HTTP 報文結構

HTTP 報文大致可分為報文首部和報文主體兩部分。兩者由最初出現的空行(CR+LF)來劃分。通常,並不一定有報文主體。如下:

HTTP 報文結構
2.1請求報文結構
請求報文結構

請求報文的首部內容由以下資料組成:

  • 請求行 —— 包含用於請求的方法、請求 URI 和 HTTP 版本。
  • 首部欄位 —— 包含表示請求的各種條件和屬性的各類首部。(通用首部、請求首部、實體首部以及RFC裡未定義的首部如 Cookie 等)

請求報文的示例,如下:

請求報文示例
2.2響應報文結構
響應報文結構

響應報文的首部內容由以下資料組成:

  • 狀態行 —— 包含表明響應結果的狀態碼、原因短語和 HTTP 版本。
  • 首部欄位 —— 包含表示請求的各種條件和屬性的各類首部。(通用首部、響應首部、實體首部以及RFC裡未定義的首部如 Cookie 等)

響應報文的示例,如下:

響應報文示例

五、HTTP 報文首部之請求行、狀態行

1.請求行

舉個栗子,下面是一個 HTTP 請求的報文:

GET  /index.htm  HTTP/1.1
Host: sample.com

其中,下面的這行就是請求行,

GET  /index.htm  HTTP/1.1
  • 開頭的 GET 表示請求訪問伺服器的型別,稱為方法;
  • 隨後的字串 /index.htm 指明瞭請求訪問的資源物件,也叫做請求 URI;
  • 最後的 HTTP/1.1,即 HTTP 的版本號,用來提示客戶端使用的 HTTP 協議功能。

綜合來看,大意是請求訪問某臺 HTTP 伺服器上的 /index.htm 頁面資源。

2.狀態行

同樣舉個栗子,下面是一個 HTTP 響應的報文:

HTTP/1.1  200  OK
Date: Mon, 10 Jul 2017 15:50:06 GMT
Content-Length: 256
Content-Type: text/html