【進階篇】一文搞清楚網頁發起 HTTP 請求呼叫的完整過程

CodeBlogMan發表於2024-07-15

目錄
  • 前言
  • 一、HTTP協議
    • 1.1基本概念
    • 1.2工作原理
  • 二、請求過程
    • 2.1域名解析
    • 2.2TCP 連線
    • 2.3傳送 HTTP 請求
    • 2.4伺服器應答
    • 2.5響應內容
    • 2.6關閉連線
  • 三、客戶端請求
    • 3.1請求Header
    • 3.2請求方法
    • 3.3cookie 和 token
  • 四、服務端響應
    • 4.1demo 舉例
    • 4.2返回內容
    • 4.3返回狀態碼
  • 五、文章小結

前言

最近筆者在實際專案開發中會頻繁涉及到服務之間的遠端呼叫、域名的配置和請求的轉發等與計算機網路相關的知識。

這些其實在讀本科和考研的時候都有學習過理論,但為了更透徹地掌握便於在工作中使用,我還是決定寫一篇文章來分享實際開發中是怎麼應用的。

下面將從 HTTP 協議的基本概念與簡介、完整的請求過程、客戶端的請求以及服務端的響應這四部分來展開,同時會使用實際的場景來加以分析,便於大家理解。


一、HTTP協議

1.1基本概念

HTTP 協議(Hyper Text Transfer Protocol)超文字傳輸協議,即傳輸文字、圖片、音訊、影片等超文字資料、是一種用於分散式、協作式和超媒體資訊系統的應用層協議。為了更快地處理大量事務,確保協議的可伸縮性,HTTP 協議被設計成了一種無狀態協議,不保留之前一切的請求或響應報文的資訊。HTTP 協議也是全球資訊網(WWW,World Wide Web)的資料通訊的基礎。

HTTP 是一個客戶端(使用者)和伺服器端(網站)請求和應答的標準,其定義了定義 Web 客戶端如何向 Web 伺服器請求 Web 頁面,以及伺服器如何把 Web 頁面響應給客戶端。

HTTP 協議中並沒有規定必須使用 TCP/IP 或其支援的層。事實上,HTTP 可以在任何網際網路協議上,或其他網路上實現。HTTP 假定其下層協議提供可靠的傳輸。因此,任何能夠提供這種保證的協議都可以被其使用,所以其在 TCP/IP 協議族使用 TCP 作為其傳輸層,而 UDP 是不可靠傳輸。

使用者透過使用各種工具(如網頁瀏覽器、網路爬蟲或者 Jmeter 等)作為客戶端,來發起一個 HTTP 請求到伺服器的指定埠(預設為80)。這個客戶端被稱為使用者代理程式(User Agent)。而接受並響應該 HTTP 請求的伺服器上會儲存著各種使用者需要的資源,比如 HTML 檔案和影像,這個被使用者請求的伺服器被稱為源伺服器(Origin Server)

1.2工作原理

通常,由 HTTP 客戶端發起一個請求,建立一個到伺服器指定埠(預設是80埠)的 TCP 連線,HTTP伺服器則在那個埠監聽客戶端的請求。一旦收到請求,伺服器會向客戶端返回一個狀態,比如"HTTP/1.1 200 OK",以及響應請求而返回的內容,如檔案、錯誤訊息、或者其它資料等。

以下是 HTTP 協議工作流程的幾個關鍵步驟:

第一步:建立 TCP/IP 連線,客戶端與伺服器透過 Socket 三次握手進行連線

第二步:客戶端向服務端發起 HTTP 請求,如:POST/login.html http/1.1

第三步:客戶端傳送請求頭部、請求內容,最後會傳送一空白行,標示客戶端請求完畢

第四步:伺服器做出應答,表示對於客戶端請求的應答,如:HTTP/1.1 200 OK

第五步:伺服器向客戶端傳送響應頭部資訊,傳送一空白行,表示應答頭資訊傳送完畢,隨後以 Content-type 要求的資料格式,傳送響應正文給客戶端

第六步:服務端關閉 TCP 連線,如果伺服器或者客戶端的 Connection:keep-alive 則表示客戶端與伺服器端繼續儲存連線,在下次請求時可以繼續使用這次的連線

二、請求過程

下面對 1.2 小節中的幾個步驟做更為細緻的講解。

2.1域名解析

瀏覽器向 DNS 伺服器請求解析該 URL 中的域名所對應的 IP 地址,查詢過程依次如下:

  1. 瀏覽器快取

    首先搜尋瀏覽器自身的 DNS 快取(快取的時間比較短,大概只有1分鐘,且只能容納1000條快取),看自身的快取中是否是有域名對應且未過期的條目。如果有,則域名解析到此結束。

  2. 作業系統快取

    如果上一步沒有找到對應的條目,瀏覽器會搜尋作業系統自身的 DNS 快取,如果找到了沒有過期的對應條目,則停止搜尋,解析到此結束。檢視作業系統自身的 DNS 快取,以 Windows 系統為例,win + R 後輸入 cmd 命令提示行,輸入ipconfig /displaydns 進行檢視。

  3. hosts 檔案

    如果上一步沒有找到對應條目,瀏覽器就會嘗試讀取作業系統本地的檔案,以 Windows 系統為例:C:\Windows\System32\drivers\etc內的 hosts 檔案。

  4. DNS 伺服器

    如果以上的三步都沒有找到對應條目,那麼瀏覽器就會向 DNS 伺服器請求進行域名解析。

    更具體地說,瀏覽器發起一個 DNS 的系統呼叫,向本地配置的首選 DNS 伺服器(一般由運營商提供)發起域名解析請求。域名解析請求是透過 UDP 協議向DNS 的 53 埠發起請求,這個請求是遞迴的請求。也就是說,運營商的 DNS 伺服器必須得提供給我們該域名的公網 IP 地址。

2.2TCP 連線

根據 DNS 伺服器解析出的 IP 地址和預設埠號,與該伺服器進行 TCP 連線中 3 次握手的前兩次,來建立連線:

【進階篇】一文搞清楚網頁發起 HTTP 請求呼叫的完整過程
TCP 連線

2.3傳送 HTTP 請求

即完成 TCP 的 3 次握手的第三次:

【進階篇】一文搞清楚網頁發起 HTTP 請求呼叫的完整過程
傳送 HTTP 請求

2.4伺服器應答

客戶端發起了請求,伺服器一定要有應答嗎?要回答這個問題,得知道 HTTP 響應的底層原理是基於 HTTP 協議的通訊機制,這個協議決定了:如果客戶端傳送的請求能準確到達伺服器,那麼伺服器必須會有響應並返回。

在本文的第四章,我會拿一個部署在 Linux 伺服器上的、基於Spring Boot 的 Java 程式來分析具體伺服器是怎麼做出響應的。

【進階篇】一文搞清楚網頁發起 HTTP 請求呼叫的完整過程
伺服器應答

2.5響應內容

下面是訪問 https://mvnrepository.com/ 即 Maven 遠端中央倉庫時,呼叫其搜尋介面所產生的響應標頭內容:

【進階篇】一文搞清楚網頁發起 HTTP 請求呼叫的完整過程
響應內容

2.6關閉連線

最後瀏覽器會關閉該 TCP 連線,瀏覽器利用自己內部的工作機制,把請求到的靜態資源和 HTML 程式碼進行渲染,呈現給使用者。


三、客戶端請求

下面其實是本文的重頭戲,會重點講解具體的 HTTP 請求是怎麼構建、傳送請求的。

3.1請求Header

一個 HTTP 請求報文由請求行(request line)、請求頭部(headers)、請求資料(request body)和空行(blank line)4個部分組成。

其中請求頭部(headers)為請求報文新增了一些附加資訊,由鍵值對組成,每行一對,名和值之間使用冒號分隔,如下圖是由 PostMan 呼叫所示:

【進階篇】一文搞清楚網頁發起 HTTP 請求呼叫的完整過程
響應內容
請求 Header

常見的幾個請求頭釋義:

【進階篇】一文搞清楚網頁發起 HTTP 請求呼叫的完整過程
常見請求頭

且我們還可以自定義 Header 如:Authorization 是認證資訊、Tenant-Code 是發起本次請求的租戶編碼。

注意:由於 HTTP 協議只規定 POST 提交的資料必須放在訊息主體(body)中,並沒有規定資料必須使用什麼編碼方式。服務端通常是根據請求頭中的 Content-Type 欄位來獲知請求中的訊息主體是用何種方式編碼,再對 body 進行解析。

常用的 Content-Type 編碼方式有:

  • application/x-www-form-urlencoded 資料在傳送到伺服器之前,會將表單內的資料轉換為鍵值對,比如 username=admin&password=123456,並將所有字元都會進行 URL 轉碼;
  • multipart/form-data 資料將被編碼為一條訊息以標籤為單元,用分隔符分開,既可以上傳鍵值對,也可以上傳檔案,通常用於上傳二進位制的檔案;
  • application/json 用來告訴服務端訊息主體是序列化後的 JSON 字串,前端無法將表單的 enctype 屬性指定為 application/json,通常使用 Ajax 的方式傳送這種編碼形式的請求。

3.2請求方法

最常用的四種請求方法:GET、POST、PUT、DELETE。

【進階篇】一文搞清楚網頁發起 HTTP 請求呼叫的完整過程
常見 HTTP 請求方法

3.3cookie 和 token

在瞭解 Session 和 Cookies 之前,我們還需要了解 HTTP 的一個特點,叫作無狀態。

HTTP 的無狀態是指 HTTP 協議對事務處理是沒有記憶能力的,也就是說伺服器不知道客戶端是什麼狀態。

這時兩個用於保持 HTTP 連線狀態的技術就出現了,它們分別是 Session 和 Cookie。

Session 在服務端,也就是網站的伺服器,用來儲存使用者的 Session 資訊。

Cookie 在客戶端,也可以理解為瀏覽器端有了 Cookie,瀏覽器在下次訪問網頁時會自動附帶上它傳送給伺服器,伺服器透過識別 Cookie 並鑑定出是哪個使用者,然後再判斷使用者是否是登入狀態,進而返回對應的響應。


四、服務端響應

4.1demo 舉例

這裡以一個基於 Spring Boot 的 Java 程式來舉例,@RequestMapping 是 Spring MVC 框架中的一個註解,它用於指示具體的 Controller 方法如何響應某個特定的請求。它可以用於將請求URL對映到控制器上,並可以指定不同的引數設定。

@RestController
@RequestMapping("/study")
public class StudyController {

    @Resource
    private StudyService studyService;

    /**
     * 新增
     * @param studyDTO
     * @return 是否成功
     */
    @PostMapping("/add")
    public BaseResponse<Boolean> addAwards(@RequestBody StudyDTO studyDTO) {
        return ResultUtils.success(studyService.addStudy(studyDTO));
    }
}

如果將這個應用部署在伺服器上,你想訪問到,那麼需要在瀏覽器中輸入:https://ip+port/服務名/study/add

我自己本地訪問則是:http://localhost:28089/initial/study/add

4.2返回內容

那麼 HTTP 返回的響應報文內容是什麼?主要包括以下3個部分:

  • 響應狀態行(Status Line):包含HTTP協議版本、響應狀態碼和狀態訊息。例如,HTTP/1.1 200 OK 表示 HTTP 協議版本是1.1,響應狀態碼是 200,狀態訊息是 OK。這個在下一節會單獨拿出來講。

  • 響應頭部(Headers):包含了一系列的鍵值對,用來描述響應的屬性和後設資料。常見的響應頭包括 Content-Type(指定響應的資料型別)、Content-Length(指定響應體的長度)等。HTTP 協議定義了許多標準的響應頭,不同的頭部欄位有不同的作用。

    以下是一些常見的響應頭:

    • Content-Type:指定響應體的資料型別。例如,Content-Type: text/html 表示響應體是 HTML 文件。

    • Content-Length:指定響應體的長度,以位元組為單位。例如,Content-Length: 1024 表示響應體的長度是 1024 位元組。

    • Location:用於重定向客戶端到新的URL。例如,Location: http://example.com/new_page 會將客戶端重定向到 http://example.com/new_page。

    • Set-Cookie:用於設定 Cookie,可以在響應中向客戶端傳送 Cookie 資訊。

    • Cache-Control:控制響應的快取行為,包括快取的過期時間、驗證方式等。

    • Server:指定響應的伺服器資訊。例如,Server: Apache/2.4.38 表示響應是由 Apache 伺服器版本 2.4.38 生成的。

  • 響應體(Body):包含了實際的響應資料,可以是HTML頁面、JSON資料、文字等。響應體的格式由Content-Type頭部欄位指定。

    以下是一些常見的Content-Type值:

    • text/html:HTML 文件。

    • application/json:JSON 資料。

    • text/plain:純文字。

    • image/jpeg:JPEG影像。

    • application/xml:XML 資料。

4.3返回狀態碼

以下是一些常見的HTTP響應狀態碼:

【進階篇】一文搞清楚網頁發起 HTTP 請求呼叫的完整過程
常見 HTTP 響應狀態碼

五、文章小結

無論是前端還是後端,不論是科班還是非科班,也無論是開發、測試還是產品,瞭解和掌握 HTTP 請求的一些基本知識都是非常重要的。它是現代網際網路中不可或缺的一部分,為我們提供了高效、靈活、可靠的資料傳輸方式,為 Web 應用程式的開發和使用提供了強有力的支援。

今天的分享就到這裡,如有不足和錯誤,還請大家指正。或者你有其它想說的,也歡迎大家在評論區交流!

參考文件:

https://blog.csdn.net/u010804417/article/details/123638124

https://www.cnblogs.com/engeng/articles/5959335.html

相關文章