計算機網路之HTTP協議

語言: CN / TW / HK

theme: condensed-night-purple highlight: atelier-cave-light


攜手創作,共同成長!這是我參與「掘金日新計劃 · 8 月更文挑戰」的第8天,點選檢視活動詳情


⭐️前面的話⭐️

本篇文章將介紹應用層中使用最為廣泛的協議,即HTTP協議,譯名叫做超文字傳輸協議,也有叫超文字轉移協議的,本文的重點內容是介紹如何進行HTTP抓包,HTTP協議的格式是怎樣的,常見的欄位與狀態碼以及對Cookie的理解。

📒部落格主頁:未見花聞的部落格主頁\ 🎉歡迎關注🔎點贊👍收藏⭐️留言📝\ 📌本文由未見花聞原創!\ 📆掘金首發時間:🌴2022年8月3日🌴\ ✉️堅持和努力一定能換來詩與遠方!\ 💭參考書籍:📚《圖解HTTP》\ 💬參考線上程式設計網站:🌐牛客網🌐力扣\ 博主的碼雲gitee,平常博主寫的程式程式碼都在裡面。\ 博主的github,平常博主寫的程式程式碼都在裡面。\ 🍭作者水平很有限,如果發現錯誤,一定要及時告知作者哦!感謝感謝!


1.HTTP概述

1.1什麼是HTTP

HTTP/HTTPS是一種應用層的協議,應用層協議很多時候都是程式設計師自己定製的,需要根據具體的場景來制定應用層協議,但是由於程式設計師水平參差不齊,大佬設計的協議很好用,菜鳥設計的協議一言難盡,於是有一些大佬就發明了很好用的協議,直接讓大家照搬,HTTP就是其中的一個典型代表,HTTP雖然已經設計好了,但是它的擴充套件性極強,可以根據需要讓程式設計師自定義資料資訊。

HTTP是一種超文字傳輸協議,是網際網路上應用最為廣泛的一種網路協議。那如何才能看到HTTP的報文格式或資訊,這就需要對HTTP進行抓包,下面介紹一下如何進行HTTP的抓包。

1.2抓包工具Fidder的使用

Fidder是一款專門抓HTTP/HTTPS包的軟體,它的原理就是充當一個代理,比如當訪問一個網站時,會先將請求傳送給Fidder,然後Fidder再把請求傳送給目標網頁的伺服器,同理伺服器返回的響應也一樣,先需要經過Fidder,再發送給客戶端。

這樣,Fidder就能夠捕獲到HTTP的請求與響應,由於Fidder充當的是一個“代理”的角色,所以使用Fiddder時不能夠有其他使用或修改代理的軟體執行,否則Fidder就不能夠捕獲到HTTP/HTTPS的包。

Fidder

1.2.1下載

下載很簡單,直接去官網下載即可,網址為http://www.telerik.com/fiddler

首先直接開啟網頁是下面這個樣子的。 官網首頁 進入官網後,我們往下翻,找到如圖的頁面,Fidder Classic,這個是免費的。 下載 點選Try to Free。 下載 點選後,會跳轉到如下的頁面。 下載 填寫資訊,下載即可。

1.2.2安裝

至於安裝,就非常簡單了,一路next就可以了。

安裝過後,需要設定一下,首先現在的大部分網頁都是HTTPS格式的,所以需要設定HTTPS的捕捉。

第一步,找到Tools選項,選擇Options,找到HTTPS。 1 將如圖的選項全部勾上,並確定。 2 然後,會有一個視窗跳出來,一定要點yes,不然就要重灌Fidder了,這樣Fidder就可以使用了。

如果Fidder一直報The system proxy was changed,click to reenable fiddler capture,這樣的警告,這種情況大概率是存在衝突的軟體,代理被修改了,參考一位大佬的部落格可以解決:http://blog.csdn.net/legend818/article/details/99724398

1.2.3如何使用

Fidder左側是捕獲到的HTTP(s)包,雙擊某個包後,會在右側顯示詳細資訊。 圖片

2 顯示詳細資訊後,使用Raw模式可以看到http的本體。 3 點選View in Notepad可以使用記事本開啟,檢視詳情。

4 對於右側的上下兩欄,上面是請求,下面是對應的響應。

我們發現響應裡面的內容有一串亂碼,這可能是壓縮或者加密了,可以點選下面黃色的按鈕來顯示伺服器的響應結果。 5 點選之後: 6 Fidder的基本使用差不多就是這些。

1.3URI與URL

URI即網路資源識別符號,URL即網路資源定位符,前者是使用唯一字串來標識網際網路中某一資源,後者使用字串來表示某個資源的位置,URL可以理解為URI的一種實現,就像介面與實現類的關係一樣。

URL(I)格式: url 協議方案名:必選項,使用 httphttps等協議方案名獲取訪問資源時要指定協議型別。不區分字母大小寫,最後附一個冒號:,使用//與後面的欄位分隔。 也可使用 jdbc:mysql://javascript: //這類jdbc程式或指令碼程式的方案名。

登入資訊:可選項,這是上古時期上網的時候,在這裡會體現出賬號與密碼,現在基本上沒有了,使用@符號與後面的欄位分隔。

伺服器地址:必選項,可以使用域名和IP地址來表示,使用:與埠號分隔,沒有埠號:省略。

埠號:可選項,表示訪問主機上哪一個應用程式,該欄位為空,瀏覽器會分配預設的埠號,http是80,https是443

檔案路徑:必選項,描述訪問伺服器的資源是什麼,最簡單的路徑就是一個/,你訪問很多網站的首頁的時候,最後都會有一個/,使用?與查詢字串分隔。

查詢字串:可選項,表示瀏覽器或者客戶端傳給伺服器自定義的資訊,對獲取的資源提出進一步的要求,一般是程式設計師自定義,所以如果不是你自己寫的,大概率看不懂,使用#與片段識別符號分隔。

片段識別符號:可選項,表示訪問頁面的子位置,能夠控制瀏覽器滾動到某一位置。

HTTP 協議使用 URI 定位網際網路上的資源。正是因為 URI 的特定功能,在網際網路上任意位置的資源都能訪問到。

URL

1.4URL encode/decode

如果查詢字串(query string)的內容包含一些具有特定含義的字元需要進行轉義,如/,?,&等,如果含有這些字元,會將這些字元替換為%字元的ASCII碼,這個過程就是encode,反過來將這些轉義的字串解析為原來的字元,這個過程就是decode

比如,你在瀏覽器上搜索C++,在URL上就會得到C%2B%2B這樣的字串。 c++

2.HTTP協議格式

2.1HTTP請求格式

2.1.1基本格式

請求格式

http請求格式包括請求行,請求報頭和請求正文,報頭與正文之間使用空行做標記進行分隔。 例如,下面的一大段http請求報文。 栗子 請求行由三部分構成,分別是方法, URL, HTTP版本號。 方法用來描述請求的目的是什麼,比如get方法一般用來獲取伺服器的資源。 URL表示想要訪問的網路資源的位置。 常見HTTP版本號有HTTP/1.0,HTTP/1.1,HTTP/2.0這些都是基於TCP,最新版本的HTTP/3.0是基於UDP。

請求頭部,包含很多行,有許多的鍵值對組成,鍵和值之間使用:來進行分割,至於鍵值對的數量,是不固定的。

請求正文是可選項,不一定會有,像上面的那個例子請求正文就是空的。 基本格式

2.1.2方法

請求行裡面的方法完整地說應該叫做告知伺服器意圖的 HTTP 方法,這裡的方法與java裡面的方法不同,引入這些方法的初衷就是為了表示不同的語義,比如GET表示獲取資源,POST表示上傳資源,但是大多數人寫程式碼就是GET/POST一把梭,基本上就沒有考慮各種方法的語義。

在http/1.1版本中,最常使用的方法有GET,POST,還有其他方法,引謝靈運的話來說,GET佔八鬥,POST佔一鬥,其他方法分剩下的一斗。

各方法功能如下: 方法 GET :獲取資源 GET 方法用來請求訪問已被 URL 識別的資源。指定的資源經伺服器端解析後返回響應內容。也就是說,如果請求的資源是文字,那就保持原樣返回;如果是像 CGI(CommonGateway Interface,通用閘道器介面)那樣的程式,則返回經過執行後的輸出結果。

get POST:傳輸實體主體 雖然用 GET 方法也可以傳輸實體的主體,但一般不用 GET 方法進行傳輸,而是用 POST方法。雖說 POST 的功能與 GET 很相似,但 POST 的主要目的並不是獲取響應的主體內容。

post PUT:傳輸檔案 PUT 方法用來傳輸檔案。就像 FTP 協議的檔案上傳一樣,要求在請求報文的主體中包含文 件內容,然後儲存到請求 URI 指定的位置。 該方法在HTTP/1.1無驗證機制,不安全,配合驗證機制可以開放使用該方法。 PUT HEAD:獲得報文首部 與GET的區別就是HEAD只返回報文的首部。

head DELETE:刪除檔案 DELETE 方法按請求 URI 刪除指定的資源,不安全,需配合驗證機制使用。 del OPTIONS:詢問支援的方法 詢問伺服器支援哪些方法。 op TRACE:追蹤路徑 TRACE 方法是讓 Web 伺服器端將之前的請求通訊環回給客戶端的方法,不常用。

tr CONNECT:要求用隧道協議連線代理 CONNECT 方法要求在與代理伺服器通訊時建立隧道,實現用隧道協議進行 TCP 通訊。主要使用 SSL(Secure Sockets Layer,安全套接層)和 TLS(Transport Layer Security,傳輸層安全)協議把通訊內容加 密後經網路隧道傳輸。

格式與其他的方法不同:

javascript CONNECT 代理伺服器名:埠號 HTTP版本

co

GET方法可以代替POST方法的使用,POST方法也可以替代GET方法的使用,那GET與POST有什麼區別?

答:GET與POST沒有本質區別,但存在細節差別。 從語義上來說,GET一般用來獲取資源,POST一般用來上傳資源,不是強制要求,只是建議。 從習慣上說,通常情況下,GET沒有body(請求正文),GET通過query string(查詢字串)傳輸資料。通常情況下,POST有body,POST通過body來傳輸資料,這也不是絕對的,只是一種習慣。 其他方面,GET請求一般是冪等的,POST請求一般不冪等,冪等的意思是,你每次輸入相同的請求得到的輸出的結果是確定的,反之不冪等就是輸出的結果是不確定的,因為相同結果得到的輸出結果相同,那麼這個結果是可以被快取的,否則就不能被快取,也就是說GET可以快取,POST不可以快取,能不能快取是與冪等是有關係的。

2.2HTTP響應格式

2.2.1基本格式

響應行

HTTP響應格式包括響應行,響應頭部,響應正文,頭部與正文之間使用空行進行分割。

例如下面的這一段響應報文。 響應栗子 響應行包括協議版本,狀態碼,狀態碼描述三部分組成。

狀態碼錶示響應的狀態是怎麼樣的,200表示成功,400,500表示失敗,狀態碼描述就是說明對應狀態碼的意思是什麼。

響應頭部,分隔符,響應正文在格式上與請求是一樣的,其中響應正文最常見的格式就是HTML。 響應報文

2.2.2狀態碼

狀態碼的職責是當客戶端向伺服器端傳送請求時,描述返回的請求結果。藉助狀態碼,使用者可以知道伺服器端是正常處理了請求,還是出現了錯誤。

狀態碼 狀態碼的大類類別: class 狀態碼個大類下的細分表:

|狀態碼與狀態資訊|該狀態下的情況| |---|---| |200 OK|表示從客戶端發來的請求在伺服器端被正常處理了。200 |204 No Content|該狀態碼代表伺服器接收的請求已成功處理,但在返回的響應報文中不含實體的主體部分。另外,也不允許返回任何實體的主體。204 | 206 Partial Content| 該狀態碼錶示客戶端進行了範圍請求,而伺服器成功執行了這部分的 GET 請求。響應報文中包含由 Content-Range 指定範圍的實體內容。206 |301 Moved Permanently|永久性重定向。該狀態碼錶示請求的資源已被分配了新的 URI,以後應使用資源現在所指的 URI。301 |302 Found|臨時性重定向。該狀態碼錶示請求的資源已被分配了新的 URI,希望使用者(本次)能使用新的 URI 訪問。302 |303 See Other|該狀態碼錶示由於請求對應的資源存在著另一個 URI,應使用 GET方法定向獲取請求的資源。303 |304 Not Modified|該狀態碼錶示客戶端傳送附帶條件的請求時,伺服器端允許請求訪問資源,但沒有滿足請求條件的資源的情況。304 |307 Temporary Redirect|臨時重定向。該狀態碼與 302 Found 有著相同的含義。儘管 302 標準禁止 POST 變換成 GET,但實際使用時大家並不遵守。307 會遵照瀏覽器標準,不會從 POST 變成 GET。但是,對於處理響應時的行為,每種瀏覽器有可能出現不同的情況。 |400 Bad Request|該狀態碼錶示請求報文中存在語法錯誤。400 |401 Unauthorized|該狀態碼錶示傳送的請求需要有通過 HTTP 認證(BASIC 認證、DIGEST 認證)的認證資訊。另外若之前已進行過 1 次請求,則表示使用者認證失敗。返回含有 401 的響應必須包含一個適用於被請求資源的 WWW-Authenticate 首部用以質詢(challenge)使用者資訊。當瀏覽器初次接收到 401 響應,會彈出認證用的對話視窗。401 |403 Forbidden|該狀態碼錶明對請求資源的訪問被伺服器拒絕了。403 |404 Not Found|該狀態碼錶明伺服器上無法找到請求的資源。除此之外,也可以在伺服器端拒絕請求且不想說明理由時使用。404 |500 Internal Server Error|該狀態碼錶明伺服器端在執行請求時發生了錯誤。也有可能是 Web應用存在的 bug 或某些臨時的故障。500 |503 Service Unavailable|該狀態碼錶明伺服器暫時處於超負載或正在進行停機維護,現在無法處理請求。503 |418 I'm a teapot|這個是http的一個彩蛋,增加樂趣,其實沒什麼用|

2.3首部欄位

2.3.1分類

HTTP 首部欄位根據實際用途被分為以下 4 種類型。 - 通用首部欄位(General Header Fields)請求報文和響應報文兩方都會使用的首部。 - 請求首部欄位(Request Header Fields)從客戶端向伺服器端傳送請求報文時使用的首部。補充了請求的附加內容、客戶端資訊、響應內容相關優先順序等資訊。 - 響應首部欄位(Response Header Fields)從伺服器端向客戶端返回響應報文時使用的首部。補充了響應的附加內容,也會要求客戶端附加額外的內容資訊。 - 實體首部欄位(Entity Header Fields)針對請求報文和響應報文的實體(正文)部分使用的首部,補充了資源內容更新時間等與實體有關的資訊。

2.3.2實體首部欄位

實體

常用的幾個欄位: Content-Length,計算body部分的長度,可以配合分隔符解決粘包問題。 Content-Type,表示body中的資料格式。

2.3.3請求首部欄位

請求 常用欄位: User-Agent,表示客戶端是使用什麼來進行上網,作業系統資訊+瀏覽器資訊。

javascript User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36

Referer,表示當前的頁面是從哪一個頁面跳轉過來的,但是不一定有,如直接輸入網址,那就沒有原來的那個跳轉頁面。

2.3.4響應首部欄位

響應

2.3.5通用首部欄位

通用

2.3.6Cookie

因為HTTP是一種無狀態的協議,它無法對之前的發生過的請求和響應狀態進行記憶,如果遇到需要登入的頁面,登入之後,再重新整理,是需要重新進行登入的,這個就非常的難受,為了解決這個問題,引入了Cookie機制。 無狀態 但是也有好處,可以減少伺服器的 CPU 及記憶體資源的消耗。

Cookie是瀏覽器為頁面提供的一種持久化儲存資料的機制,即就是將資料儲存磁碟上,不會因為瀏覽器或者電腦重啟而導致資料丟失。

Cookie會按照域名來進行分類並組織,針對每一個域名,都會分配一個“小房間”(一塊獨立的儲存空間),這些小房間之間是相互獨立的,在每個“小房間”裡面會按照鍵值對的方式儲存資料(值),每個鍵值對之間使用&來進行分隔。

那Cookie的資料從哪裡來?其實是從伺服器返回給客戶端的,伺服器完成客戶端的身份認證之後會通過的頭部欄位Set-Cookie來給客戶端響應資訊。 cookset

就像下面伺服器返回的Cookie一樣: Cookie

Cookie的作用其實就像醫院裡面的就診卡一樣,就診卡里面有就診人的基本資訊,刷卡之後會根據這些基本資訊可以查出在當前醫院裡面的歷史就診記錄等更加詳細的資訊,這張就診卡就相當於Cookie,而根據就診卡資訊獲得的詳細記錄叫做session,每個session裡面記錄了就診使用者的許多關鍵資訊,例如歷史就診記錄,要做的檢測等等,每一個session都有對應的sessionId,即會話標識,伺服器返回給客戶端的Cookie響應就有這個會話標識,然後訪問後續頁面的,根據這個會話標識就能從伺服器找到對應的資訊進行登入,這樣重新整理頁面就不用在重複登入了。

下圖所圈的部分就有可能就是一種sessionId。 sessionid


下期預告:HTTP請求構造