一、HTTP協議
1.1 基本概念:
?HTTP全稱超文本傳輸協議,是一種無狀態的、應用層的協議,它基于請求/響應模型。客戶端(通常是Web瀏覽器)通過發送HTTP請求到服務器來獲取或發送信息,服務器則返回HTTP響應作為回應。HTTP協議定義了客戶端和服務器之間交換消息的格式和過程,使得數據能夠在網絡上以統一的方式傳輸。
1.2 HTTP工作原理
?HTTP工作在TCP/IP協議棧的應用層,通常使用80端口進行通信。一個完整的HTTP交互流程包括以下幾個步驟:
- 建立TCP 連接:客戶端與服務器建立一個TCP連接,這是數據傳輸的前提;
- 發送HTTP請求:客戶端向服務器發送一個HTTP請求,(如GET /index.html)、請求頭部和請求體;
- 服務器處理請求:服務器解析器跪求并定位請求資源,如果需要i的話,服務器會執行相應的業務邏輯;
- 返回HTTP相應:服務器將響應數據封裝成HTTP響應,包括響應狀態行(如200 OK)、響應頭部和響應體,然后發送回客戶端。
- 關閉 TCP 連接:通信結束后,TCP連接可以被關閉,或者在持續連接(Keep-Alive)的情況下保持打開狀態以供后續請求復用。
二、 數據報文結構
?HTTP 是一個文本格式的協議. 可以通過 Chrome 開發者工具或者 Fiddler 抓包, 分析 HTTP 請求/響應的細節.
2.1 HTTP 請求格式
POST https://beacons.gvt2.com/domainreliability/upload HTTP/1.1
Host: beacons.gvt2.com
Connection: keep-alive
Content-Length: 638
Content-Type: application/json; charset=utf-8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9{"entries":[{"failure_data":{"custom_error":"net::ERR_CONNECTION_TIMED_OUT"},"network_changed":false,"protocol":"","request_age_ms":136344,"request_elapsed_ms":21374,"sample_rate":1.0,"server_ip":"[2404:6800:4008:c04::54]:443","status":"tcp.connection.timed_out","url":"https://accounts.google.com/","was_proxied":false},{"failure_data":{"custom_error":"net::ERR_CONNECTION_TIMED_OUT"},"network_changed":false,"protocol":"","request_age_ms":136344,"request_elapsed_ms":21374,"sample_rate":1.0,"server_ip":"59.24.3.174:443","status":"tcp.connection.timed_out","url":"https://accounts.google.com/","was_proxied":false}],"reporter":"chrome"}
2.2 HTTP 響應格式
HTTP/1.1 200 OK
Report-To: {"endpoints":[{"priority":1,"url":"https://beacons.gcp.gvt2.com/domainreliability/upload-nel","weight":1},{"priority":1,"url":"https://beacons.gvt2.com/domainreliability/upload-nel","weight":1},{"priority":1,"url":"https://beacons2.gvt2.com/domainreliability/upload-nel","weight":1},{"priority":1,"url":"https://beacons3.gvt2.com/domainreliability/upload-nel","weight":1},{"priority":1,"url":"https://beacons4.gvt2.com/domainreliability/upload-nel","weight":1},{"priority":1,"url":"https://clients2.google.com/domainreliability/upload-nel","weight":1},{"priority":2,"url":"https://beacons5.gvt2.com/domainreliability/upload-nel","weight":1},{"priority":2,"url":"https://beacons5.gvt3.com/domainreliability/upload-nel","weight":1}],"group":"nel","max_age":300}
NEL: {"failure_fraction":1,"include_subdomains":false,"max_age":300,"report_to":"nel","success_fraction":0.25}
Content-Type: application/javascript; charset=utf-8
Date: Wed, 26 Jun 2024 02:45:34 GMT
Server: Domain Reliability Server
Content-Length: 0
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
為什么 HTTP 報文中要存在 “空行”?
?因為 HTTP 協議并沒有規定報頭部分的鍵值對有多少個。空行就相當于是 “報頭的結束標記”,或者是 “報頭和正文之間的分隔符”。TTP 在傳輸層依賴 TCP 協議, TCP 是面向字節流的。 如果沒有這個空行, 就會出現 "粘包問題。
HTTP之 URI 和URL
URL,全稱是UniformResourceLocator, 中文叫統一資源定位符,是互聯網上用來標識某一處資源的地址, 以下面的這個URL 為例;
http://user:pass@www.example.jp:80/dir/index.htm?boardID=5&ID=24618&page=1#name
一個完整的 URL 主要包括一下幾個部分
-
協議部分:該URL的協議部分為“http:”,這代表網頁使用的是HTTP協議。在Internet中可以使用多種協議,如HTTP,FTP等等本例中使用的是HTTP協議。在"HTTP"后面的“//”為分隔符;
-
域名部分:該URL的域名部分為“user:pass@www.example.jp”。一個URL中,也可以使用IP地址作為域名使用;
-
端口部分:跟在域名后面的是端口,域名和端口之間使用“:”作為分隔符。端口不是一個URL必須的部分,如果省略端口部分,將采用默認端口;
-
擬目錄部分:從域名后的第一個“/”開始到最后一個“/”為止,是虛擬目錄部分。虛擬目錄也不是一個URL必須的部分。本例中的虛擬目錄是“/news/”;
-
文件名部分:從域名后的最后一個“/”開始到“?”為止,是文件名部分,如果沒有“?”,則是從域名后的最后一個“/”開始到“#”為止,是文件部分,如果沒有“?”和“#”,那么從域名后的最后一個“/”開始到結束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一個URL必須的部分,如果省略該部分,則使用默認的文件名;
-
錨部分:從“#”開始到最后,都是錨部分。本例中的錨部分是“name”。錨部分也不是一個URL必須的部分
-
參數部分:從“?”開始到“#”為止之間的部分為參數部分,又稱搜索部分、查詢部分。本例中的參數部分為“boardID=5&ID=24618&page=1”。參數可以允許有多個參數,參數與參數之間用“&”作為分隔符。
URI,全稱是uniform resource identifier,統一資源標識符,用來唯一的標識一個資源。
?Web上可用的每種資源如HTML文檔、圖像、視頻片段、程序等都是一個來URI來定位的URI一般由三部組成:
- 訪問資源的命名機制
- 存放資源的主機名
- 資源自身的名稱,由路徑表示,著重強調于資源。
三、HTTP方法
HTTP定義了多種請求方法,常用的有:
- GET: 用于請求指定資源。
- POST: 用于提交數據到指定資源。
- PUT: 用于更新指定資源。
- DELETE: 用于刪除指定資源。
- HEAD: 類似于GET,但只返回響應頭(獲取報文首部)。
- OPTIONS: 用于描述目標資源的通信選項(詢問支持的方法)。
- CONNECT: 用于建立網絡隧道。
- Link:建立和資源之間的聯系.
- TRACE: 用于回顯服務器收到的請求(追蹤路徑)。
3.1 GET方法
?GET 是最常用的 HTTP 方法. 常用于獲取服務器上的某個資源。在瀏覽器中直接輸入 URL, 此時瀏覽器就會發送出一個 GET 請求.另外, HTML 中的 link, img, script 等標簽, 也會觸發 GET 請求。
GET 請求的特點
- 首行的第一部分為 GET
- URL 的 query string 可以為空, 也可以不為空.
- header 部分有若干個鍵值對結構.
- body 部分為空。
關于 GET 請求的 URL 長度問題:
- HTTP 協議由 RFC 2616 標準定義, 標準原文中明確說明: “Hypertext Transfer Protocol --HTTP/1.1,” does not specify any requirement for URL length.沒有對 URL 的長度有任何的限制.
- 實際 URL 的長度取決于瀏覽器的實現和 HTTP 服務器端的實現. 在瀏覽器端, 不同的瀏覽器最大長度是不同的, 但是現代瀏覽器支持的長度一般都很長; 在服務器端, 一般這個長度是可以配置的.
3.2 POST方法
? POST 方法也是一種常見的方法. 多用于提交用戶輸入的數據給服務器(例如登陸頁面)。通過 HTML 中的 form 標簽可以構造 POST 請求, 或者使用 JavaScript 的 ajax 也可以構造 POST 請求。
POST 請求的特點
- 首行的第一部分為 POST
- URL 的 query string 一般為空 (也可以不為空)
- header 部分有若干個鍵值對結構.
- body 部分一般不為空. body 內的數據格式通過 header 中的 Content-Type 指定. body 的長度由header 中的 Content-Length 指定
經典面試題: 談談 GET 和 POST 的區別
- 語義不同: GET 一般用于獲取數據,POST 一般用于提交數據;
- GET 的 body 一般為空,需要傳遞的數據通過 query string 傳遞,POST 的 query string 一般為空,需要傳遞的數據通過 body 傳遞;
- GET 請求一般是冪等的,POST 請求一般是不冪等的。(如果多次請求得到的結果一樣, 就視為請求是冪等的).
- GET可以被緩存,POST不能被緩存.(這一點也是承接冪等性)
四、HTTP 狀態碼 (重點)
HTTP響應狀態碼分為五大類:
*** 1xx (信息性響應): 表示接收的請求正在處理。
- 2xx (成功響應): 表示請求正常處理完畢。
- 3xx (重定向消息): 表示需要進行附加操作以完成請求。
- 4xx (客戶端錯誤): 表示客戶端請求出錯。
- 5xx (服務器錯誤): 表示服務器處理請求出錯。**
總結
?以上就是今天要講的內容,本文介紹了HTTP協議的基礎知識,包括其無狀態、應用層協議的特性,基于請求/響應的工作模式,以及TCP連接、HTTP請求和響應的流程。HTTP方法如GET、POST、PUT等用于不同操作,狀態碼則表示請求結果。