在日常上網瀏覽網頁、刷視頻時,背后都離不開 HTTP 協議的支持。作為 Web 世界的 “交通規則”,它負責服務器和客戶端瀏覽器之間的數據傳輸。這篇文章就帶大家全面了解 HTTP 協議,從基本概念到通信細節,再到安全相關的 HTTPS,讓你對它有清晰的認知。
一、HTTP 協議是什么?
HTTP 協議,全名叫 Hyper Text Transfer Protocol(超文本傳輸協議),是應用層里專門用來在服務器和客戶端瀏覽器之間傳輸超文本數據的協議。像我們平時看到的文字、圖片、視頻、音頻這些,都靠它來傳遞。
它不只是個簡單的傳輸協議,還是個雙向協議,工作在 “瀏覽器 - 服務器” 架構下。簡單說就是:瀏覽器把請求數據發給服務器,服務器處理完請求后,再把響應信息回傳給瀏覽器。
二、HTTP 協議怎么通信?
HTTP 屬于應用層協議,默認用 80 端口,在傳輸層會借助 TCP 協議來傳數據。整個通信過程分 11 步,咱們結合瀏覽器和服務器(比如 Tomcat)的交互來看看:
- 用戶在瀏覽器上發起新請求,比如輸入網址按回車;
- 瀏覽器向服務器發送 TCP 連接請求;
- 服務器和瀏覽器通過 TCP 三次握手,建立起 TCP 連接;
- 瀏覽器按照 HTTP 協議格式,生成請求數據包(也就是 HTTP 請求報文);
- 把這個請求數據包發給服務器;
- 服務器按照 HTTP 協議格式,解析收到的請求報文;
- 服務器執行請求處理,調用相關的業務邏輯方法,生成響應數據;
- 服務器再按照 HTTP 協議格式,把響應數據打包成響應數據包(HTTP 響應報文);
- 服務器把響應數據包發送給瀏覽器;
- 瀏覽器按照 HTTP 協議格式,解析響應數據包;
- 瀏覽器把響應數據包里的內容顯示在頁面上,用戶就能看到網頁了。
三、URL:定位資源的 “地址”
HTTP 協議靠 URL(Uniform Resource Locator,統一資源定位符)來找到要訪問的資源,它的格式是:http://host [":"port] [abs_path]
給大家舉個例子:http://192.168.0.116:8080/index.html
,這里每個部分的意思很明確:
- “http” 表示用 HTTP 協議定位網絡資源;
- “host” 是合法的 Internet 主機域名或者 IP 地址,比如例子里的 “192.168.0.116”;
- “port” 是端口號,要是沒寫就用默認的 80 端口,例子里用的是 8080 端口;
- “abs_path” 是請求資源的 URI,例子里就是 “/index.html”。
這里得提一下 URL 和 URI、URN 的關系。URL 是 URI(Uniform Resource Identifier,統一資源標識符)的子集,它在 URI 的基礎上多了定位資源的能力。而 URI 除了包含 URL,還包含 URN(Uniform Resource Name,統一資源名稱)。URN 只用來定義資源的名稱,沒法定位資源,比如 “urn:isbn:0451450523”,這只是一本書的 ISBN 編號,能確定是哪本書,但沒法知道在哪兒能找到這本書。
簡單總結下三者的關系:URI 是大概念,下面分了 URL 和 URN,URL 能定位資源,URN 只能命名資源。
四、HTTP 報文:數據傳輸的 “包裹”
HTTP 報文分請求報文和響應報文,就像快遞包裹一樣,里面裝著通信需要的各種信息。
4.1 請求報文
瀏覽器通過 URL 發請求時,會把請求信息打包成 HTTP 請求報文發給服務器。它的結構分四部分:
- 第一行是請求行,包含請求方式、URL、協議版本,比如 “GET /index.html HTTP/1.1”;
- 接下來幾行是 HTTP 請求首部,里面有多個首部字段,用來傳遞額外的請求信息;
- 一個空行,作用是分隔首部和后面的內容主體 Body;
- 最后是請求的內容主體,也就是要傳給服務器的數據(不是所有請求都有)。
4.2 響應報文
服務器處理完請求后,會把響應信息裝進 HTTP 響應報文回傳給瀏覽器。它的結構和請求報文類似,也分四部分:
- 第一行是狀態行,包含協議版本、狀態碼和描述,最常見的就是 “HTTP/1.1 200 OK”,表示請求成功;
- 接下來幾行是響應首部,同樣有多個首部字段;
- 一個空行,分隔首部和內容主體;
- 最后是響應的內容主體,也就是服務器返回給瀏覽器的數據,比如網頁的 HTML 代碼。
給大家看個 HTTP 響應報文的示例(實際報文會更復雜,這里是簡化版):
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 1234<html>
<body>
響應內容
</body>
</html>
五、常用的 HTTP 請求方式
HTTP 請求報文的第一行(請求行)里會指定請求方式,常見的有 GET、POST、HEAD、PUT、DELETE、OPTIONS 這幾種,各自的用途不一樣:
請求方式 | 用途 | 特點 |
---|---|---|
GET | 獲取資源 | 只檢索數據,不影響資源;參數通過 URL 傳遞;冪等且可緩存 |
POST | 提交數據增加資源 | 用來創建或增加資源;兩個相同請求不會覆蓋;參數通過 Request Body 傳遞;非冪等且不可緩存 |
HEAD | 獲取響應報頭 | 和 GET 類似,但只返回響應報頭,沒有內容主體;常用于確認 URL 有效性和資源更新時間 |
PUT | 修改資源 | 用來更新資源;兩個相同請求會覆蓋;數據通過內容主體傳遞;冪等 |
DELETE | 刪除資源 | 用來刪除指定資源;冪等 |
OPTIONS | 查詢支持的方法 | 詢問指定 URL 支持哪些請求方式;返回結果會包含 “Allow: GET, POST, HEAD, OPTIONS” 這類內容 |
這里重點說下 GET 和 POST 的區別,這倆是平時用得最多的:
- 用途不同:GET 是拿數據,POST 是提交數據;
- 請求報文格式有差異:POST 的請求行是 “POST /URL HTTP/1.1 \r\n”,GET 的是 “GET /URL HTTP/1.1 \r\n”;
- 參數傳遞方式不一樣:GET 的參數在 URL 里,POST 的參數在 Request Body 里;
- 冪等性和緩存不同:GET 是冪等(多次執行結果一樣)且能緩存,POST 是非冪等且不能緩存。
六、HTTP 首部字段:傳遞額外信息的 “小紙條”
HTTP 首部字段就像通信時附帶的 “小紙條”,用來傳遞額外的信息,比如服務器域名、數據長度、內容類型等等。下面給大家介紹幾個常用的:
- Host 字段:瀏覽器發請求時,用來指定服務器的域名。示例:
Host: www.apesource.com
- Content-Length 字段:服務器返回響應時,告訴瀏覽器本次響應數據的長度。示例:
Content-Length: 1000
- Connection 字段:瀏覽器用來要求服務器使用長連接,方便后續請求復用。示例:
Connection: keep-alive
(要是想斷開連接,就寫Connection: close
) - Content-Type 字段:服務器告訴瀏覽器,本次響應數據的類型和編碼。示例:
Content-Type: text/html; charset=utf-8
(表示是 HTML 文件,編碼是 UTF-8) - Accept 字段:瀏覽器發請求時,說明自己能接受哪些格式的響應數據。示例:
Accept: */*
(表示所有格式都能接受) - Content-Encoding 字段:服務器告訴瀏覽器,響應數據用的壓縮格式。示例:
Content-Encoding: gzip
- Accept-Encoding 字段:瀏覽器告訴服務器,自己能處理哪些壓縮格式。示例:
Accept-Encoding: gzip, deflate
七、HTTP 狀態碼:請求結果的 “反饋信號”
服務器返回的響應報文里,狀態行中的狀態碼就像 “反饋信號”,告訴瀏覽器請求處理的結果。狀態碼分 5 大類,每類有不同的含義:
7.1 1XX:信息提示
這類狀態碼是協議處理中的中間狀態,實際用得很少,主要是告訴瀏覽器 “請求正在處理中”。
7.2 2XX:請求成功
表示服務器成功處理了請求,常見的有:
- 200 OK:最常用的,說明請求完全成功,響應里有完整的內容主體;
- 204 No Content:和 200 OK 類似,但響應報文沒有內容主體;
- 206 Partial Content:用于分塊下載或斷點續傳,說明返回的只是資源的一部分。
7.3 3XX:重定向
表示客戶端請求的資源位置變了,需要用新的 URL 重新請求,常見的有:
- 301 Moved Permanently:永久重定向,說明原來的資源沒了,以后都得用新 URL 訪問;
- 302 Found:臨時重定向,資源還在,但暫時得用另一個 URL 訪問。
7.4 4XX:客戶端錯誤
表示瀏覽器發的請求有問題,服務器沒法處理,常見的有:
- 400 Bad Request:請求報文格式錯了,服務器看不懂;
- 403 Forbidden:服務器不讓訪問這個資源,不是請求格式的問題;
- 404 Not Found:請求的資源在服務器上找不到;
- 405 Not Allowed:服務器不支持瀏覽器用的這種請求方式。
7.5 5XX:服務器錯誤
表示請求沒問題,但服務器處理時出了內部錯誤,常見的有:
- 500 Internal Server Error:服務器內部出了未知錯誤;
- 501 Not Implemented:瀏覽器請求的功能,服務器還沒實現;
- 502 Bad Gateway:服務器作為網關或代理時,訪問后端服務器出錯了(自身沒問題);
- 503 Service Unavailable:服務器現在太忙了,暫時沒法響應請求,建議稍后再試。
八、連接管理:讓通信更高效
HTTP 的連接管理主要涉及短連接、長連接和管線化連接,目的是減少通信開銷,提高效率。
8.1 短連接和長連接
- 短連接:HTTP/1.0 默認用的是短連接。每次通信都要重新 TCP 三次握手建立連接,響應完就 TCP 四次揮手斷開。這樣頻繁建立和斷開連接,開銷很大。
- 長連接:HTTP/1.1 改成了默認長連接(也叫持久性連接)。建立一次 TCP 連接就能進行多次 HTTP 通信,不用每次都重新連,大大減少了開銷,還能減輕服務器壓力。
這里要注意兩點:
- HTTP/1.0 里要是想用長連接,得在請求里加
Connection: Keep-Alive
; - HTTP/1.1 里要是想斷開長連接,客戶端或服務器得發
Connection: close
。
8.2 管線化連接
管線化連接是把多個 HTTP 請求批量提交的技術,發請求時不用等服務器先響應前一個。不過這得基于長連接,而且只有 HTTP/1.1 支持,HTTP/1.0 不支持。
比如以前發兩個請求,得等第一個請求的響應回來,再發第二個;有了管線化,能同時把兩個請求發出去,服務器處理完再依次返回響應,效率更高。
九、HTTPS:給 HTTP 加層 “安全鎖”
HTTP 協議因為用明文傳輸,存在不少安全問題,而 HTTPS 就是為了解決這些問題而生的。
9.1 HTTP 的安全隱患
HTTP 用明文傳數據,會有三個主要問題:
- 內容可能被竊聽:比如數據被抓包,里面的信息就能被看到;
- 通信方身份可能被偽裝:比如遇到釣魚網站,你以為是正規網站,其實是假的;
- 報文可能被篡改:比如傳輸過程中,數據被改了(像強制植入廣告),還沒法發現。
9.2 什么是 HTTPS?
HTTPS 不是新協議,而是在 HTTP 和 TCP 之間加了一層 SSL(Secure Sockets Layer,安全套接層)。簡單說就是:HTTP 先和 SSL 通信,再由 SSL 和 TCP 通信。通過 SSL,HTTPS 有了加密(防竊聽)、認證(防偽裝)、完整性保護(防篡改)這三個能力。
9.3 HTTP 和 HTTPS 的區別
- 安全性不同:HTTP 明文傳輸,不安全;HTTPS 加了 SSL,加密傳輸,安全;
- 連接建立過程不同:HTTP 只要 TCP 三次握手就能傳報文;HTTPS 在 TCP 三次握手后,還要進行 SSL 握手,才能傳加密報文;
- 端口不同:HTTP 默認 80 端口,HTTPS 默認 443 端口;
- 證書要求不同:HTTPS 需要向 CA(證書權威機構)申請數字證書,證明服務器身份;HTTP 不用。
9.4 兩種加密方式
HTTPS 的加密主要用兩種方式,各有優缺點:
9.4.1 對稱密鑰加密
加密和解密用同一個密鑰。優點是運算速度快,缺點是沒法安全地把密鑰傳給對方 —— 要是密鑰在傳輸過程中被偷了,加密就沒意義了。
9.4.2 非對稱密鑰加密
也叫公開密鑰加密,加密和解密用不同的密鑰(一個公鑰,一個私鑰)。公鑰誰都能拿,私鑰只有自己有。
- 加密過程:發送方用接收方的公鑰加密數據,接收方用自己的私鑰解密;
- 簽名過程:發送方用自己的私鑰簽名,接收方用發送方的公鑰驗證簽名,能確認發送方身份。
優點是公鑰傳輸安全,缺點是運算速度慢。
9.5 HTTPS 的工作原理
HTTPS 的工作過程其實就是結合了兩種加密方式,既保證安全又兼顧速度,具體步驟如下:
- 用戶用瀏覽器訪問 HTTPS 網站,服務器收到請求后,選擇瀏覽器支持的加密和哈希算法,然后把數字證書(里面包含頒發機構、網址、公鑰、有效期等信息)返回給瀏覽器;
- 瀏覽器校驗證書:要是證書有問題(比如過期、不被信任),會彈出警告;要是沒問題,就生成一個隨機秘鑰 X,用證書里的公鑰加密后發給服務器;
- 服務器收到加密后的隨機秘鑰 X,用自己的私鑰解密,得到 X;然后用 X 對網頁內容加密,發給瀏覽器;
- 瀏覽器用之前生成的隨機秘鑰 X 和約定的加密算法,解密服務器發來的內容,最后把網頁顯示給用戶。
到這里,HTTP 協議的核心內容就講完了。從基本概念到通信流程,再到安全升級的 HTTPS,相信大家對 HTTP 有了更全面的認識。如果有疑問,歡迎在評論區交流~