本篇文章將介紹應(yīng)用層中使用最為廣泛的協(xié)議,即HTTP協(xié)議,譯名叫做超文本傳輸協(xié)議,也有叫超文本轉(zhuǎn)移協(xié)議的,本文的重點(diǎn)內(nèi)容是介紹如何進(jìn)行HTTP抓包,HTTP協(xié)議的格式是怎樣的,常見的字段與狀態(tài)碼以及對Cookie的理解。
1.HTTP概述
1.1什么是HTTP
HTTP/HTTPS是一種應(yīng)用層的協(xié)議,應(yīng)用層協(xié)議很多時(shí)候都是程序員自己定制的,需要根據(jù)具體的場景來制定應(yīng)用層協(xié)議,但是由于程序員水平參差不齊,大佬設(shè)計(jì)的協(xié)議很好用,菜鳥設(shè)計(jì)的協(xié)議一言難盡,于是有一些大佬就發(fā)明了很好用的協(xié)議,直接讓大家照搬,HTTP就是其中的一個(gè)典型代表,HTTP雖然已經(jīng)設(shè)計(jì)好了,但是它的擴(kuò)展性極強(qiáng),可以根據(jù)需要讓程序員自定義數(shù)據(jù)信息。
HTTP是一種超文本傳輸協(xié)議,是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議。那如何才能看到HTTP的報(bào)文格式或信息,這就需要對HTTP進(jìn)行抓包,下面介紹一下如何進(jìn)行HTTP的抓包。
1.2抓包工具Fidder的使用
Fidder是一款專門抓HTTP/HTTPS包的軟件,它的原理就是充當(dāng)一個(gè)代理,比如當(dāng)訪問一個(gè)網(wǎng)站時(shí),會(huì)先將請求發(fā)送給Fidder,然后Fidder再把請求發(fā)送給目標(biāo)網(wǎng)頁的服務(wù)器,同理服務(wù)器返回的響應(yīng)也一樣,先需要經(jīng)過Fidder,再發(fā)送給客戶端。
這樣,F(xiàn)idder就能夠捕獲到HTTP的請求與響應(yīng),由于Fidder充當(dāng)?shù)氖且粋€(gè)“代理”的角色,所以使用Fiddder時(shí)不能夠有其他使用或修改代理的軟件運(yùn)行,否則Fidder就不能夠捕獲到HTTP/HTTPS的包。
1.2.1下載
下載很簡單,直接去官網(wǎng)下載即可,網(wǎng)址為www.telerik.com/fiddler。
首先直接打開網(wǎng)頁是下面這個(gè)樣子的。
進(jìn)入官網(wǎng)后,我們往下翻,找到如圖的頁面,F(xiàn)idder Classic,這個(gè)是免費(fèi)的。
點(diǎn)擊Try to Free。
點(diǎn)擊后,會(huì)跳轉(zhuǎn)到如下的頁面。
填寫信息,下載即可。
1.2.2安裝
至于安裝,就非常簡單了,一路next就可以了。
安裝過后,需要設(shè)置一下,首先現(xiàn)在的大部分網(wǎng)頁都是HTTPS格式的,所以需要設(shè)置HTTPS的捕捉。
第一步,找到Tools選項(xiàng),選擇Options,找到HTTPS。
將如圖的選項(xiàng)全部勾上,并確定。
然后,會(huì)有一個(gè)窗口跳出來,一定要點(diǎn)yes,不然就要重裝Fidder了,這樣Fidder就可以使用了。
如果Fidder一直報(bào)The system proxy was changed,click to reenable fiddler capture,這樣的警告,這種情況大概率是存在沖突的軟件,代理被修改了,參考一位大佬的博客可以解決:blog.csdn.NET/legend818/a…
1.2.3如何使用
Fidder左側(cè)是捕獲到的HTTP(s)包,雙擊某個(gè)包后,會(huì)在右側(cè)顯示詳細(xì)信息。
顯示詳細(xì)信息后,使用Raw模式可以看到http的本體。
點(diǎn)擊View in Notepad可以使用記事本打開,查看詳情。
對于右側(cè)的上下兩欄,上面是請求,下面是對應(yīng)的響應(yīng)。
我們發(fā)現(xiàn)響應(yīng)里面的內(nèi)容有一串亂碼,這可能是壓縮或者加密了,可以點(diǎn)擊下面黃色的按鈕來顯示服務(wù)器的響應(yīng)結(jié)果。
點(diǎn)擊之后:
Fidder的基本使用差不多就是這些。
1.3URI與URL
URI即網(wǎng)絡(luò)資源標(biāo)識符,URL即網(wǎng)絡(luò)資源定位符,前者是使用唯一字符串來標(biāo)識互聯(lián)網(wǎng)中某一資源,后者使用字符串來表示某個(gè)資源的位置,URL可以理解為URI的一種實(shí)現(xiàn),就像接口與實(shí)現(xiàn)類的關(guān)系一樣。
URL(I)格式:
協(xié)議方案名:必選項(xiàng),使用 http 或https等協(xié)議方案名獲取訪問資源時(shí)要指定協(xié)議類型。不區(qū)分字母大小寫,最后附一個(gè)冒號:,使用//與后面的字段分隔。 也可使用 jdbc:MySQL:// 或 JAVAscript: //這類jdbc程序或腳本程序的方案名。
登錄信息:可選項(xiàng),這是上古時(shí)期上網(wǎng)的時(shí)候,在這里會(huì)體現(xiàn)出賬號與密碼,現(xiàn)在基本上沒有了,使用@符號與后面的字段分隔。
服務(wù)器地址:必選項(xiàng),可以使用域名和IP地址來表示,使用:與端口號分隔,沒有端口號:省略。
端口號:可選項(xiàng),表示訪問主機(jī)上哪一個(gè)應(yīng)用程序,該字段為空,瀏覽器會(huì)分配默認(rèn)的端口號,http是80,https是443。
文件路徑:必選項(xiàng),描述訪問服務(wù)器的資源是什么,最簡單的路徑就是一個(gè)/,你訪問很多網(wǎng)站的首頁的時(shí)候,最后都會(huì)有一個(gè)/,使用?與查詢字符串分隔。
查詢字符串:可選項(xiàng),表示瀏覽器或者客戶端傳給服務(wù)器自定義的信息,對獲取的資源提出進(jìn)一步的要求,一般是程序員自定義,所以如果不是你自己寫的,大概率看不懂,使用#與片段標(biāo)識符分隔。
片段標(biāo)識符:可選項(xiàng),表示訪問頁面的子位置,能夠控制瀏覽器滾動(dòng)到某一位置。
HTTP 協(xié)議使用 URI 定位互聯(lián)網(wǎng)上的資源。正是因?yàn)?URI 的特定功能,在互聯(lián)網(wǎng)上任意位置的資源都能訪問到。
1.4URL encode/decode
如果查詢字符串(query string)的內(nèi)容包含一些具有特定含義的字符需要進(jìn)行轉(zhuǎn)義,如/,?,&等,如果含有這些字符,會(huì)將這些字符替換為%字符的ASCII碼,這個(gè)過程就是encode,反過來將這些轉(zhuǎn)義的字符串解析為原來的字符,這個(gè)過程就是decode。
比如,你在瀏覽器上搜索C++,在URL上就會(huì)得到C%2B%2B這樣的字符串。
2.HTTP協(xié)議格式
2.1HTTP請求格式
2.1.1基本格式
http請求格式包括請求行,請求報(bào)頭和請求正文,報(bào)頭與正文之間使用空行做標(biāo)記進(jìn)行分隔。 例如,下面的一大段http請求報(bào)文。
請求行由三部分構(gòu)成,分別是方法, URL, HTTP版本號。 方法用來描述請求的目的是什么,比如get方法一般用來獲取服務(wù)器的資源。 URL表示想要訪問的網(wǎng)絡(luò)資源的位置。 常見HTTP版本號有HTTP/1.0,HTTP/1.1,HTTP/2.0這些都是基于TCP,最新版本的HTTP/3.0是基于UDP。
請求頭部,包含很多行,有許多的鍵值對組成,鍵和值之間使用:來進(jìn)行分割,至于鍵值對的數(shù)量,是不固定的。
請求正文是可選項(xiàng),不一定會(huì)有,像上面的那個(gè)例子請求正文就是空的。
2.1.2方法
請求行里面的方法完整地說應(yīng)該叫做告知服務(wù)器意圖的 HTTP 方法,這里的方法與java里面的方法不同,引入這些方法的初衷就是為了表示不同的語義,比如GET表示獲取資源,POST表示上傳資源,但是大多數(shù)人寫代碼就是GET/POST一把梭,基本上就沒有考慮各種方法的語義。
在http/1.1版本中,最常使用的方法有GET,POST,還有其他方法,引謝靈運(yùn)的話來說,GET占八斗,POST占一斗,其他方法分剩下的一斗。
各方法功能如下:
GET :獲取資源 GET 方法用來請求訪問已被 URL 識別的資源。指定的資源經(jīng)服務(wù)器端解析后返回響應(yīng)內(nèi)容。也就是說,如果請求的資源是文本,那就保持原樣返回;如果是像 CGI(CommonGateway Interface,通用網(wǎng)關(guān)接口)那樣的程序,則返回經(jīng)過執(zhí)行后的輸出結(jié)果。
POST:傳輸實(shí)體主體 雖然用 GET 方法也可以傳輸實(shí)體的主體,但一般不用 GET 方法進(jìn)行傳輸,而是用 POST方法。雖說 POST 的功能與 GET 很相似,但 POST 的主要目的并不是獲取響應(yīng)的主體內(nèi)容。
PUT:傳輸文件 PUT 方法用來傳輸文件。就像 FTP 協(xié)議的文件上傳一樣,要求在請求報(bào)文的主體中包含文 件內(nèi)容,然后保存到請求 URI 指定的位置。 該方法在HTTP/1.1無驗(yàn)證機(jī)制,不安全,配合驗(yàn)證機(jī)制可以開放使用該方法。
HEAD:獲得報(bào)文首部 與GET的區(qū)別就是HEAD只返回報(bào)文的首部。
DELETE:刪除文件 DELETE 方法按請求 URI 刪除指定的資源,不安全,需配合驗(yàn)證機(jī)制使用。
OPTIONS:詢問支持的方法 詢問服務(wù)器支持哪些方法。
TRACE:追蹤路徑 TRACE 方法是讓 Web 服務(wù)器端將之前的請求通信環(huán)回給客戶端的方法,不常用。
CONNECT:要求用隧道協(xié)議連接代理 CONNECT 方法要求在與代理服務(wù)器通信時(shí)建立隧道,實(shí)現(xiàn)用隧道協(xié)議進(jìn)行 TCP 通信。主要使用 SSL(Secure Sockets Layer,安全套接層)和 TLS(Transport Layer Security,傳輸層安全)協(xié)議把通信內(nèi)容加 密后經(jīng)網(wǎng)絡(luò)隧道傳輸。
格式與其他的方法不同:
CONNECT 代理服務(wù)器名:端口號 HTTP版本
GET方法可以代替POST方法的使用,POST方法也可以替代GET方法的使用,那GET與POST有什么區(qū)別?
答:GET與POST沒有本質(zhì)區(qū)別,但存在細(xì)節(jié)差別。 從語義上來說,GET一般用來獲取資源,POST一般用來上傳資源,不是強(qiáng)制要求,只是建議。 從習(xí)慣上說,通常情況下,GET沒有body(請求正文),GET通過query string(查詢字符串)傳輸數(shù)據(jù)。通常情況下,POST有body,POST通過body來傳輸數(shù)據(jù),這也不是絕對的,只是一種習(xí)慣。 其他方面,GET請求一般是冪等的,POST請求一般不冪等,冪等的意思是,你每次輸入相同的請求得到的輸出的結(jié)果是確定的,反之不冪等就是輸出的結(jié)果是不確定的,因?yàn)橄嗤Y(jié)果得到的輸出結(jié)果相同,那么這個(gè)結(jié)果是可以被緩存的,否則就不能被緩存,也就是說GET可以緩存,POST不可以緩存,能不能緩存是與冪等是有關(guān)系的。
2.2HTTP響應(yīng)格式
2.2.1基本格式
HTTP響應(yīng)格式包括響應(yīng)行,響應(yīng)頭部,響應(yīng)正文,頭部與正文之間使用空行進(jìn)行分割。
例如下面的這一段響應(yīng)報(bào)文。
響應(yīng)行包括協(xié)議版本,狀態(tài)碼,狀態(tài)碼描述三部分組成。
狀態(tài)碼表示響應(yīng)的狀態(tài)是怎么樣的,200表示成功,400,500表示失敗,狀態(tài)碼描述就是說明對應(yīng)狀態(tài)碼的意思是什么。
響應(yīng)頭部,分隔符,響應(yīng)正文在格式上與請求是一樣的,其中響應(yīng)正文最常見的格式就是html。
2.2.2狀態(tài)碼
狀態(tài)碼的職責(zé)是當(dāng)客戶端向服務(wù)器端發(fā)送請求時(shí),描述返回的請求結(jié)果。借助狀態(tài)碼,用戶可以知道服務(wù)器端是正常處理了請求,還是出現(xiàn)了錯(cuò)誤。
狀態(tài)碼的大類類別:
狀態(tài)碼個(gè)大類下的細(xì)分表:
狀態(tài)碼與狀態(tài)信息 |
該狀態(tài)下的情況 |
200 OK |
表示從客戶端發(fā)來的請求在服務(wù)器端被正常處理了。
|
204 No Content |
該狀態(tài)碼代表服務(wù)器接收的請求已成功處理,但在返回的響應(yīng)報(bào)文中不含實(shí)體的主體部分。另外,也不允許返回任何實(shí)體的主體。
|
206 Partial Content |
該狀態(tài)碼表示客戶端進(jìn)行了范圍請求,而服務(wù)器成功執(zhí)行了這部分的 GET 請求。響應(yīng)報(bào)文中包含由 Content-Range 指定范圍的實(shí)體內(nèi)容。
|
301 Moved Permanently |
永久性重定向。該狀態(tài)碼表示請求的資源已被分配了新的 URI,以后應(yīng)使用資源現(xiàn)在所指的 URI。
|
302 Found |
臨時(shí)性重定向。該狀態(tài)碼表示請求的資源已被分配了新的 URI,希望用戶(本次)能使用新的 URI 訪問。
|
303 See Other |
該狀態(tài)碼表示由于請求對應(yīng)的資源存在著另一個(gè) URI,應(yīng)使用 GET方法定向獲取請求的資源。
|
304 Not Modified |
該狀態(tài)碼表示客戶端發(fā)送附帶條件的請求時(shí),服務(wù)器端允許請求訪問資源,但沒有滿足請求條件的資源的情況。
|
307 Temporary Redirect |
臨時(shí)重定向。該狀態(tài)碼與 302 Found 有著相同的含義。盡管 302 標(biāo)準(zhǔn)禁止 POST 變換成 GET,但實(shí)際使用時(shí)大家并不遵守。307 會(huì)遵照瀏覽器標(biāo)準(zhǔn),不會(huì)從 POST 變成 GET。但是,對于處理響應(yīng)時(shí)的行為,每種瀏覽器有可能出現(xiàn)不同的情況。 |
400 Bad Request |
該狀態(tài)碼表示請求報(bào)文中存在語法錯(cuò)誤。
|
401 Unauthorized |
該狀態(tài)碼表示發(fā)送的請求需要有通過 HTTP 認(rèn)證(BASIC 認(rèn)證、DIGEST 認(rèn)證)的認(rèn)證信息。另外若之前已進(jìn)行過 1 次請求,則表示用戶認(rèn)證失敗。返回含有 401 的響應(yīng)必須包含一個(gè)適用于被請求資源的 WWW-Authenticate 首部用以質(zhì)詢(challenge)用戶信息。當(dāng)瀏覽器初次接收到 401 響應(yīng),會(huì)彈出認(rèn)證用的對話窗口。
|
403 Forbidden |
該狀態(tài)碼表明對請求資源的訪問被服務(wù)器拒絕了。
|
404 Not Found |
該狀態(tài)碼表明服務(wù)器上無法找到請求的資源。除此之外,也可以在服務(wù)器端拒絕請求且不想說明理由時(shí)使用。
|
500 Internal Server Error |
該狀態(tài)碼表明服務(wù)器端在執(zhí)行請求時(shí)發(fā)生了錯(cuò)誤。也有可能是 Web應(yīng)用存在的 bug 或某些臨時(shí)的故障。
|
503 Service Unavailable |
該狀態(tài)碼表明服務(wù)器暫時(shí)處于超負(fù)載或正在進(jìn)行停機(jī)維護(hù),現(xiàn)在無法處理請求。
|
418 I'm a teapot |
這個(gè)是http的一個(gè)彩蛋,增加樂趣,其實(shí)沒什么用 |
2.3首部字段
2.3.1分類
HTTP 首部字段根據(jù)實(shí)際用途被分為以下 4 種類型。
- 通用首部字段(General Header Fields)請求報(bào)文和響應(yīng)報(bào)文兩方都會(huì)使用的首部。
- 請求首部字段(Request Header Fields)從客戶端向服務(wù)器端發(fā)送請求報(bào)文時(shí)使用的首部。補(bǔ)充了請求的附加內(nèi)容、客戶端信息、響應(yīng)內(nèi)容相關(guān)優(yōu)先級等信息。
- 響應(yīng)首部字段(Response Header Fields)從服務(wù)器端向客戶端返回響應(yīng)報(bào)文時(shí)使用的首部。補(bǔ)充了響應(yīng)的附加內(nèi)容,也會(huì)要求客戶端附加額外的內(nèi)容信息。
- 實(shí)體首部字段(Entity Header Fields)針對請求報(bào)文和響應(yīng)報(bào)文的實(shí)體(正文)部分使用的首部,補(bǔ)充了資源內(nèi)容更新時(shí)間等與實(shí)體有關(guān)的信息。
2.3.2實(shí)體首部字段
常用的幾個(gè)字段: Content-Length,計(jì)算body部分的長度,可以配合分隔符解決粘包問題。 Content-Type,表示body中的數(shù)據(jù)格式。
2.3.3請求首部字段
常用字段: User-Agent,表示客戶端是使用什么來進(jìn)行上網(wǎng),操作系統(tǒng)信息+瀏覽器信息。
User-Agent: Mozilla/5.0 (windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36
復(fù)制代碼
Referer,表示當(dāng)前的頁面是從哪一個(gè)頁面跳轉(zhuǎn)過來的,但是不一定有,如直接輸入網(wǎng)址,那就沒有原來的那個(gè)跳轉(zhuǎn)頁面。
2.3.4響應(yīng)首部字段
2.3.5通用首部字段
2.3.6Cookie
因?yàn)镠TTP是一種無狀態(tài)的協(xié)議,它無法對之前的發(fā)生過的請求和響應(yīng)狀態(tài)進(jìn)行記憶,如果遇到需要登錄的頁面,登錄之后,再刷新,是需要重新進(jìn)行登錄的,這個(gè)就非常的難受,為了解決這個(gè)問題,引入了Cookie機(jī)制。
但是也有好處,可以減少服務(wù)器的 CPU 及內(nèi)存資源的消耗。
Cookie是瀏覽器為頁面提供的一種持久化儲(chǔ)存數(shù)據(jù)的機(jī)制,即就是將數(shù)據(jù)存儲(chǔ)磁盤上,不會(huì)因?yàn)闉g覽器或者電腦重啟而導(dǎo)致數(shù)據(jù)丟失。
Cookie會(huì)按照域名來進(jìn)行分類并組織,針對每一個(gè)域名,都會(huì)分配一個(gè)“小房間”(一塊獨(dú)立的儲(chǔ)存空間),這些小房間之間是相互獨(dú)立的,在每個(gè)“小房間”里面會(huì)按照鍵值對的方式儲(chǔ)存數(shù)據(jù)(值),每個(gè)鍵值對之間使用&來進(jìn)行分隔。
那Cookie的數(shù)據(jù)從哪里來?其實(shí)是從服務(wù)器返回給客戶端的,服務(wù)器完成客戶端的身份認(rèn)證之后會(huì)通過的頭部字段Set-Cookie來給客戶端響應(yīng)信息。
就像下面服務(wù)器返回的Cookie一樣:
Cookie的作用其實(shí)就像醫(yī)院里面的就診卡一樣,就診卡里面有就診人的基本信息,刷卡之后會(huì)根據(jù)這些基本信息可以查出在當(dāng)前醫(yī)院里面的歷史就診記錄等更加詳細(xì)的信息,這張就診卡就相當(dāng)于Cookie,而根據(jù)就診卡信息獲得的詳細(xì)記錄叫做session,每個(gè)session里面記錄了就診用戶的許多關(guān)鍵信息,例如歷史就診記錄,要做的檢測等等,每一個(gè)session都有對應(yīng)的sessionId,即會(huì)話標(biāo)識,服務(wù)器返回給客戶端的Cookie響應(yīng)就有這個(gè)會(huì)話標(biāo)識,然后訪問后續(xù)頁面的,根據(jù)這個(gè)會(huì)話標(biāo)識就能從服務(wù)器找到對應(yīng)的信息進(jìn)行登錄,這樣刷新頁面就不用在重復(fù)登錄了。
下圖所圈的部分就有可能就是一種sessionId。
作者:未見花聞
鏈接:
https://juejin.cn/post/7127647111352418311