《圖解HTTP》讀後總結與淺談

最近花了一些時間讀完《圖解HTTP》,於是決定寫一篇讀書筆記,以記錄書本大致內容,也正好當作一次複習。

📢 本文由 gemini-2.5-flash 翻譯

本文章由 Hiyoung 編寫

第一章:了解 Web 及網路基礎

1.1 簡介

為了理解 HTTP,應事先了解一下 TCP/IP 協定家族。我們通常使用的網路(包括網際網路)是在 TCP/IP 協定家族的基礎上運作,而 HTTP 屬於其內部的一個子集。在網際網路上的設備若要相互通訊,雙方就必須遵從相同的規則,我們將這些規則稱為協定。(TCP/IP 是對網際網路相關的各類協定家族的一個總稱,包括但不限於:PPPoE、HTTP、TCP、IP、UDP、IEEE 802.3…)

在 TCP/IP 協定家族中,按照層次從上到下分為:應用層、傳輸層、網路層、資料鏈結層。

image 網際網路協定套件-維基百科

在使用 TCP/IP 協定家族進行通訊時,用戶端會從應用層往下走,伺服端會從資料鏈結層往上走。用戶端在層與層之間傳輸資料時,每經過一層時會為其加上該層的段首資訊。相反地,伺服端會一層一層地消去首部。這種將資料資訊包裝起來的方法叫做封裝。

image

1.2 IP、TCP 與 DNS

1.2.1 IP 協定

IP 協定位於網路層,TCP/IP 中的 IP 指的是 IP 協定,與 IP 位址並非同一回事。IP 協定的作用是將各種資料封包傳送給對方。各種 IP 位址可以和 MAC 位址進行配對。IP 位址可變換,但 MAC 位址基本上不會更改。IP 位址指明了節點被分配到的位址,MAC 位址是指網路卡所屬的固定位址。

1.2.2 MAC 位址

IP 之間的通訊依賴 MAC 位址。通常會使用 ARP 協定 來根據通訊方的 IP 位址反查出對應的 MAC 位址。

1.2.3 TCP 協定

按層次分,TCP 位於傳輸層,提供位元組流服務(Byte Stream Service)——為了方便傳輸,將大塊資料分割成以報文段(segment)為單位的資料封包進行管理。簡而言之,TCP 協定為了更容易傳送大數據才將資料分割,而且 TCP 協定能夠確認資料最終是否送達對方。

為了確認資料是否送達對方,TCP 採用了三次握手策略。握手過程中使用了 TCP 的旗標(flag)——SYN(synchronize)和 ACK(acknowledgement)。

image

1.2.4 負責網域名稱解析的 DNS 服務

電腦既可以被賦予 IP 位址,也可以被賦予主機名和網域名稱。DNS 協定提供透過網域名稱查找 IP 位址,或逆向從 IP 位址反查網域名稱的服務。

image

1.3 URL 與 URI

1.3.1 區別與關係

與 URI(統一資源識別碼)相比,我們更熟悉 URL(Uniform Resource Locator,統一資源定位符)。URL 正是使用網頁瀏覽器等存取網頁時需要輸入的網頁位址。例如 https://www.bilibili.com/ 就是 URL。URI 用字串識別某個網際網路資源,而 URL 表示資源的地點(網際網路上所處的位置)。可見 URL 是 URI 的子集。URI 可被視為定位符(URL)、名稱(URN)或兩者兼具。 統一資源名稱 (URN)如同一個人的名稱,而 統一資源定位符 (URL)代表一個人的住址。換言之,URN 定義某事物的身份,而 URL 提供查找該事物的方法。

1.3.2 URI 格式

表示指定的 URI,要使用涵蓋所有必要資訊的絕對 URI、絕對 URL 以及相對 URL。

相對 URL,是指從瀏覽器中基本 URI 處指定的 URL,形如 /image/logo.gif。

絕對 URI 的格式:

image

登入資訊(認證):指定使用者名稱和密碼作為從伺服端獲取資源時必要的登入資訊(身份認證)。此項是可選項。

伺服器位址:使用絕對 URI 必須指定待存取的伺服器位址。位址可以是類似 hackr.jp 這種 DNS 可解析的名稱,或是 192.168.1.1 這類 IPv4 位址名稱,還可以是 [0:0:0:0:0:0:0:1] 這樣用方括號括起來的 IPv6 位址名稱。

伺服器連接埠號:指定伺服器連接的網路連接埠號。此項也是可選項,若使用者省略則自動使用預設連接埠號。

帶層次的文件路徑:指定伺服器上的檔案路徑來定位特指的資源。這與 UNIX 系統的檔案目錄結構相似。

查詢字串:針對已指定的檔案路徑內的資源,可以使用查詢字串傳入任意參數。此項為可選項。

片段識別符:使用片段識別符通常可標記出已獲取資源中的子資源(文件內的某個位置)。但在 RFC 中並沒有明確規定其使用方法。該項也為可選項。

第二章:簡單的 HTTP 協定

2.1 HTTP 簡介

HTTP 是一種不保存狀態的協定,所謂不保存狀態是指 HTTP 協定本身並不會對每次的請求和回應之間的通訊狀態進行保存。所以引入了 Cookie 技術來保存通訊狀態。(註:這本 HTTP 書籍出版較早,現在使用保存狀態的技術是由 cookie、session 和 token 共同實現的)

2.2 常用的 HTTP 方法

GET:獲取資源

GET 方法是用來請求 URL 指定的資源。指定資源經伺服端解析後返回回應內容。

image

POST:傳輸實體主體

POST 用於向伺服器傳輸資料,當獲取的資料過大時也會使用 POST 方法。

GET 與 POST 的區別:

先下結論,GET 與 POST 方法沒有實質區別,只是報文格式不同。

請求參數長度限制:GET 請求長度最多 1024kb,POST 對請求資料沒有限制。

請求參數:GET 請求參數是透過 URL 傳遞的,多個參數以 & 連接,POST 請求放在 request body 中。 請求快取:GET 請求會被快取,而 POST 請求不會,除非手動設定。 安全性:POST 比 GET 安全,GET 請求在瀏覽器回溯時是無害的,而 POST 會再次請求。 歷史紀錄:GET 請求參數會被完整保留在歷史紀錄裡,而 POST 中的參數不會被保留。 編碼方式:GET 請求只能進行 URL 編碼,而 POST 支援多種編碼方式。 對參數的資料類型:GET 只接受 ASCII 字元,而 POST 沒有限制。

此外, HTTP 還有 PUT、HEAD、DELETE 等方法 在此不細細展開。

2.3 HTTP 的持久連線(三次握手四次揮手)

持久連線的特點是,只要任意一端沒有明確提出斷開連線,則保持 TCP 連線狀態。

image

三次握手:建立 TCP 連線 四次揮手:斷開 TCP 連線

在持久連線中使用管線化技術,可以不用等待回應即可直接傳送下一個請求。

image

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

image

Cookie 資訊是在伺服端產生並傳送給用戶端進行保存的。

第三章 HTTP 報文資訊

3.1 HTTP 的請求與回應報文結構

用於 HTTP 協定交互的資訊被稱為 HTTP 報文。請求端(用戶端)的 HTTP 報文叫做請求報文,回應端(伺服端)的叫做回應報文。由 8 位元組流組成,透過 HTTP 通訊傳輸。

請求行:包含用於請求的方法、請求 URI 和 HTTP 版本。

狀態行:包含表明回應結果的狀態碼、原因短語和 HTTP 版本。

首部欄位:包含表示請求與回應的各種條件和屬性的各類首部。一般有 4 種首部,分別是:通用首部、請求首部、回應首部和實體首部。

其他:可能包含 HTTP 的 RFC 裡未定義的首部(Cookie 等)。

image

3.2 編碼傳輸與分塊傳輸

HTTP 在傳輸資料過程中,透過編碼提升傳輸速率。

3.2.1 報文主體與實體主體的差異

實體:作為請求或回應的有效負載資料(補充項)被傳輸,其內容由實體首部和實體主體組成。

HTTP 報文的主體用於傳輸請求或回應的實體主體。**通常,報文主體等於實體主體。**只有當傳輸中進行編碼操作時,實體主體的內容發生變化,才導致它與報文主體產生差異。

3.2.2 分割傳送實體主體

在 HTTP 通訊過程中傳輸大容量資料時,透過將資料分割成多塊,能讓瀏覽器逐步顯示頁面。將實體主體分塊的功能稱為分塊傳輸編碼。分塊傳輸編碼會將實體主體分成多個塊。每一塊都會用十六進制來標記塊的大小,而實體主體的最後一塊會使用「0(CR+LF)」來標記。

image

所謂的塊也就是常稱的封包。

第四章 返回結果的 HTTP 狀態碼

4.1 狀態碼的類別

藉助狀態碼,使用者可以知道伺服器是否正常處理了請求,狀態碼種類繁多但常用的大概只有 14 種。

image

4.2 2XX 成功

4.2.1 200 OK

表示從用戶端傳來的請求在伺服端被正常處理了。在回應報文內,隨狀態碼一起返回的資訊會因方法的不同而發生改變。

4.2.2 204 No Content

該狀態碼代表伺服器接收的請求已成功處理,但在返回的回應報文中不含實體的主體部分。

4.3 3XX 重導向

重點介紹一下 301 重導向與 302 重導向,還有其他狀態碼可自行查看。

4.3.1 301 Moved Permanently

301 重導向是永久性的重導向。該狀態碼表示請求的資源已被分配了新的 URI,以後應使用資源現在所指的 URI。例如像下方給出的請求 URI,當指定資源路徑的最後忘記添加斜線「/」時,就會產生 301 狀態碼。

http://excample.com/sample

4.3.2 302 Found

302 重導向是臨時性的重導向。該狀態碼表示請求的資源已被分配了新的 URI,希望使用者(本次)能使用新的 URI 存取。與 301 Moved Permanently 狀態碼相似,但 302 狀態碼代表的資源不是被永久移動,只是臨時性質的。

4.4 4XX 用戶端錯誤

有 400 Bad Request、401 Unauthorized、403 Forbidden、404 Not Found。重點介紹一下 404 Not Found。

4.4.1 404 Not Found

該狀態碼表明伺服器上無法找到請求的資源。除此之外,也可以在伺服端拒絕請求且不想說明理由時使用。

4.5 5XX 伺服端錯誤

5XX 的回應結果表明伺服器本身發生錯誤。

第五章 Web 伺服器

5.1 通訊資料轉發程式:代理、閘道器、隧道

5.1.1 代理

代理伺服器的基本行為就是接收用戶端傳送的請求後轉發給其他伺服器。代理不改變請求 URI,會直接傳送給前方持有資源的目標伺服器。值得一提的是,代理是指對用戶端的代理(也稱為前向代理),而反向代理是指對伺服器的代理。

image

使用代理伺服器可以利用快取技術減少網路頻寬的流量,有時也會為了資訊安全而使用代理。

  • 快取代理

代理轉發回應時,快取代理(Caching Proxy)會預先將資源的副本(快取)保存在代理伺服器上。當代理再次接收到對相同資源的請求時,就可以不從來源伺服器那裡獲取資源,而是將之前快取的資源作為回應返回。

  • 反向代理

反向代理的優點有很多:

對用戶端隱藏伺服器(叢集)的 IP 位址
安全:作為 應用層防火牆 ,為網站提供對基於 Web 的攻擊行為(例如 DoS / DDoS )的防護,更容易排除 惡意軟體
為後端伺服器(叢集)統一提供加密和 SSL 加速(如 SSL 終端代理)
負載平衡 ,若伺服器叢集中有負載較高者,反向代理透過 URL 重寫 ,根據連線請求從負載較低者獲取與所需相同的資源或備援
對於靜態內容及短時間內有大量存取請求的動態內容提供 快取服務
對一些內容進行 壓縮 ,以節約 頻寬 或為網路頻寬不佳的網路提供服務

image

5.1.2 閘道器

image

閘道器的工作機制與代理十分相似。而閘道器能使通訊線路上的伺服器提供非 HTTP 協定服務。