HTTP(Hypertext Transfer Protocol,超文本傳輸協議)是互聯網中客戶端與服務器之間傳輸超文本(如HTML、圖片、JSON等)的核心協議,基于請求-響應模型和TCP/IP協議族工作。其完整工作流程可拆解為以下9個核心步驟,涵蓋從用戶觸發請求到最終資源展示的全鏈路細節:
步驟1:用戶觸發請求(客戶端發起意圖)
HTTP交互的起點是用戶的操作,例如:
- 在瀏覽器地址欄輸入URL(如
https://www.example.com/index.html
); - 點擊網頁中的鏈接、提交表單、加載圖片/CSS/JS等資源;
- 手機App調用API接口(如
GET /api/user
)。
此時,客戶端(瀏覽器、App等)需要明確:要訪問的服務器是誰?要獲取的資源是什么?
步驟2:解析URL(確定目標服務器與資源路徑)
客戶端首先解析用戶輸入的URL(Uniform Resource Locator,統一資源定位符),提取關鍵信息以定位目標。URL的基本結構為:
[協議]://[域名/IP]:[端口]/[路徑]?[查詢參數]#[錨點]
例如http://www.example.com:80/path/file.html?id=1#top
中:
- 協議:
http
(或https
,后者基于TLS加密); - 域名/IP:
www.example.com
(需轉換為IP地址); - 端口:
80
(HTTP默認端口,可省略;HTTPS默認443); - 路徑:
/path/file.html
(服務器上的資源路徑); - 查詢參數:
?id=1
(向服務器傳遞的額外參數,如GET請求的參數); - 錨點:
#top
(僅客戶端使用,用于定位頁面內位置,不發送給服務器)。
步驟3:DNS域名解析(將域名轉換為IP地址)
URL中的“域名”(如www.example.com
)是人類易讀的標識,而計算機通信依賴IP地址(如192.168.1.1
)。因此,客戶端需要通過DNS(域名系統) 將域名解析為IP地址,流程如下:
- 檢查本地緩存:客戶端(瀏覽器、操作系統)先查本地DNS緩存(如瀏覽器緩存、hosts文件、系統緩存),若有記錄直接使用。
- 遞歸查詢本地DNS服務器:若本地無緩存,客戶端向“本地DNS服務器”(如運營商提供的
114.114.114.114
)發送查詢請求(遞歸查詢:客戶端只等結果,不關心中間過程)。 - 迭代查詢根域名服務器:本地DNS服務器若無記錄,會向“根域名服務器”(全球共13組)查詢。根服務器返回頂級域名服務器(如
.com
服務器)的地址。 - 查詢頂級域名服務器:本地DNS服務器向
.com
服務器查詢example.com
的權威服務器地址。 - 查詢權威域名服務器:本地DNS服務器向
example.com
的權威服務器查詢www.example.com
的IP地址,最終獲取結果。 - 返回結果并緩存:本地DNS服務器將IP地址返回給客戶端,并緩存該記錄(緩存時間由域名的TTL(Time To Live)決定,通常幾分鐘到幾小時)。
舉例:www.example.com
最終解析為203.0.113.5
。
步驟4:建立TCP連接(基于三次握手)
HTTP協議依賴TCP(傳輸控制協議) 提供可靠的字節流傳輸(保證數據不丟失、不重復、按序到達)。因此,客戶端需先與服務器的目標端口(如80)建立TCP連接,通過三次握手實現:
- 第一次握手(客戶端→服務器):客戶端發送
SYN
(同步)報文,包含一個隨機序列號(如seq=100
),表示“我要連接你”。 - 第二次握手(服務器→客戶端):服務器接收
SYN
后,回復SYN+ACK
(同步+確認)報文,包含:- 確認號
ack=101
(客戶端序列號+1,表示已收到客戶端的SYN
); - 服務器自己的隨機序列號
seq=200
。
- 確認號
- 第三次握手(客戶端→服務器):客戶端接收
SYN+ACK
后,回復ACK
(確認)報文,包含確認號ack=201
(服務器序列號+1,表示已收到服務器的SYN
)。
三次握手完成后,TCP連接建立,雙方可開始傳輸數據。
注意:
- HTTP/1.0默認“非持久連接”(每次請求后關閉TCP連接);
- HTTP/1.1默認“持久連接”(
Keep-Alive
,連接保持一段時間復用,減少握手開銷); - HTTP/2通過“多路復用”在一個TCP連接上并行處理多個請求;
- HTTP/3基于QUIC協議(UDP),無需三次握手,連接建立更快。
步驟5:客戶端構建并發送HTTP請求報文
TCP連接建立后,客戶端向服務器發送HTTP請求報文,包含“要做什么”“要什么資源”等信息。請求報文結構由4部分組成:
1. 請求行(Request Line)
格式:[請求方法] [請求URI] [HTTP版本]
- 請求方法:表示客戶端對資源的操作意圖,常見包括:
GET
:獲取資源(如頁面、圖片,參數在URL中,無請求體);POST
:提交數據(如表單,參數在請求體中,更安全);PUT
:更新資源(全量替換);DELETE
:刪除資源;HEAD
:類似GET,但只返回響應頭(用于檢查資源是否存在)。
- 請求URI:服務器上的資源路徑(如
/path/file.html
)。 - HTTP版本:如
HTTP/1.1
(主流)、HTTP/2
。
示例:GET /index.html HTTP/1.1
2. 請求頭(Request Headers)
由多個“鍵值對”組成(格式:Key: Value
),用于傳遞客戶端信息、請求附加條件等,常見字段:
Host
:目標服務器域名(如www.example.com
,HTTP/1.1必需,用于虛擬主機區分);User-Agent
:客戶端標識(如Mozilla/5.0 (Windows NT 10.0; ...)
,服務器可據此返回適配內容);Accept
:客戶端可接受的資源類型(如text/html, application/json
);Accept-Encoding
:客戶端支持的壓縮方式(如gzip, deflate
,服務器可壓縮響應體減小傳輸量);Cookie
:客戶端存儲的鍵值對(如sessionid=abc123
,用于身份識別,由服務器通過Set-Cookie
設置);Connection: Keep-Alive
:請求保持TCP連接(HTTP/1.1默認)。
示例:
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml
Cookie: username=test; sessionid=abc123
3. 空行
一個單獨的CRLF
(回車+換行,\r\n
),用于分隔請求頭和請求體。
4. 請求體(Request Body)
可選,僅在POST
/PUT
等方法中存在,用于傳遞數據(如表單數據、JSON)。
- 表單數據(
Content-Type: application/x-www-form-urlencoded
):username=test&password=123
; - JSON數據(
Content-Type: application/json
):{"username":"test","password":"123"}
。
完整請求報文示例:
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml
Cookie: username=test; sessionid=abc123 (空行)
(GET方法無請求體)
步驟6:服務器接收并處理請求
服務器(如Nginx、Apache、Tomcat)通過監聽端口(如80)接收請求報文后,按以下流程處理:
- 解析請求報文:提取請求方法、URI、版本、請求頭、請求體等信息。
- 驗證請求合法性:
- 檢查
Host
是否匹配服務器配置(虛擬主機場景); - 驗證權限(如Cookie中的session是否有效,是否登錄);
- 檢查請求格式(如
Content-Length
是否與請求體長度一致)。
- 檢查
- 定位資源并處理:
- 靜態資源(如
.html
、.jpg
):直接從服務器文件系統讀取(如Nginx直接返回/var/www/html/index.html
); - 動態資源(如API接口):通過CGI、FastCGI、WSGI等接口調用后端程序(如Python的Django、Java的Spring),執行邏輯(如查詢數據庫、處理數據)。
- 靜態資源(如
- 生成響應內容:后端程序處理完成后,生成響應數據(如HTML頁面、JSON結果),返回給服務器。
步驟7:服務器構建并發送HTTP響應報文
服務器處理完成后,向客戶端返回HTTP響應報文,包含“處理結果”“返回資源”等信息。響應報文結構與請求報文類似,由4部分組成:
1. 狀態行(Status Line)
格式:[HTTP版本] [狀態碼] [原因短語]
- HTTP版本:如
HTTP/1.1
; - 狀態碼:3位數字,表示請求處理結果,分為5類:
1xx
(信息):請求已接收,繼續處理(如100 Continue
);2xx
(成功):請求正常處理(如200 OK
);3xx
(重定向):需進一步操作(如301 Moved Permanently
永久重定向,302 Found
臨時重定向);4xx
(客戶端錯誤):請求有誤(如404 Not Found
資源不存在,403 Forbidden
權限不足);5xx
(服務器錯誤):服務器處理失敗(如500 Internal Server Error
)。
- 原因短語:狀態碼的文字描述(如
OK
對應200
)。
示例:HTTP/1.1 200 OK
2. 響應頭(Response Headers)
傳遞服務器信息、響應附加條件等,常見字段:
Content-Type
:響應體的MIME類型(如text/html; charset=utf-8
表示HTML文本,image/jpeg
表示JPG圖片);Content-Length
:響應體的字節長度(客戶端可據此判斷是否接收完整);Content-Encoding
:響應體的壓縮方式(如gzip
,客戶端需解壓);Set-Cookie
:服務器向客戶端設置Cookie(如sessionid=abc123; Path=/; Max-Age=3600
);Cache-Control
:緩存控制(如max-age=3600
表示客戶端可緩存1小時);Location
:重定向的目標URL(配合3xx
狀態碼使用)。
示例:
Content-Type: text/html; charset=utf-8
Content-Length: 1024
Set-Cookie: sessionid=def456; Path=/; Max-Age=3600
Cache-Control: max-age=3600
3. 空行
同樣是CRLF
,分隔響應頭和響應體。
4. 響應體(Response Body)
服務器返回的實際資源內容,如:
- HTML文本(
<html><body>Hello</body></html>
); - JSON數據(
{"code":200,"data":"success"}
); - 二進制數據(圖片、視頻等)。
完整響應報文示例:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 150
Set-Cookie: sessionid=def456; Path=/; Max-Age=3600 (空行)
<html> <head><title>Example</title></head> <body>Hello, World!</body>
</html>
步驟8:客戶端接收并解析響應
客戶端(如瀏覽器)接收響應報文后,按以下邏輯處理:
- 解析狀態碼:判斷請求是否成功(如
200
則繼續,404
則顯示“頁面不存在”)。 - 處理響應頭:
- 若有
Set-Cookie
,則保存Cookie到本地(用于后續請求); - 若有
Cache-Control
,則緩存響應體(下次請求可直接使用緩存); - 若狀態碼為
3xx
,則根據Location
重定向到新URL。
- 若有
- 解析響應體:
- 瀏覽器:渲染HTML(解析DOM)、執行JS、加載CSS/圖片等(這些資源可能觸發新的HTTP請求);
- App:解析JSON/XML數據,更新界面。
步驟9:關閉或復用TCP連接
響應處理完成后,TCP連接的生命周期取決于HTTP版本:
-
HTTP/1.0(非持久連接):默認每次請求后關閉連接,通過四次揮手:
- 客戶端發送
FIN
(結束)報文; - 服務器回復
ACK
確認; - 服務器發送
FIN
報文; - 客戶端回復
ACK
確認。
- 客戶端發送
-
HTTP/1.1(持久連接):默認開啟
Keep-Alive
(可通過Connection: close
關閉),連接保持一段時間(如30秒),期間客戶端可復用連接發送新請求,減少握手開銷。 -
HTTP/2:通過“多路復用”在一個TCP連接上并行處理多個請求(無需等待前一個請求完成),效率更高。
-
HTTP/3:基于QUIC協議(UDP),連接建立更快(無需三次握手),且支持“連接遷移”(網絡切換時不中斷連接)。
總結
HTTP工作流程是“客戶端發起請求→DNS解析→TCP連接→請求報文傳輸→服務器處理→響應報文返回→客戶端解析→連接管理”的閉環,每個環節都依賴具體的協議規則(如DNS解析、TCP握手、HTTP報文格式)。理解這一流程有助于排查網絡問題(如404錯誤、連接超時)、優化性能(如復用連接、合理緩存)。