在之前的幾篇文章中,我們學(xué)會(huì)了Fiddler的基本原理和抓取手機(jī)流量的設(shè)置,我們已經(jīng)能夠在Fiddler上看到五顏六色的報(bào)文在歡快的跑動(dòng)了。在之前的第一講中我們大體介紹了Fiddler主界面的幾個(gè)組成部分,接下來(lái)的幾篇教程我們主要來(lái)介紹一下各個(gè)功能的簡(jiǎn)單的操作和實(shí)用的快捷鍵,今天我們先學(xué)習(xí)的是花花綠綠的報(bào)文跑動(dòng)著的SessionList區(qū)。
Session是什么?
對(duì)HTTP協(xié)議有些許了解的同學(xué)應(yīng)該知道,一個(gè)完整的HTTP會(huì)話是由Request和Response兩部分組成的,客戶端向服務(wù)器發(fā)出請(qǐng)求(Request),服務(wù)器針對(duì)性的給出回應(yīng)(Response),他們總是成對(duì)出現(xiàn)的,在Fiddler中我們把這樣的一對(duì)消息稱做一個(gè)Session。一個(gè)Session的生命周期大體可以分成四個(gè)部分:
- 客戶端發(fā)送請(qǐng)求給Fiddler
- Fiddler處理后轉(zhuǎn)發(fā)請(qǐng)求給Server
- Server返回Response給Fiddler
- Fiddler處理后轉(zhuǎn)發(fā)Response給客戶端
Fiddler在收到客戶端發(fā)來(lái)的報(bào)文后就在SessionList列表中添加一個(gè)新記錄,在沒(méi)收到服務(wù)器Response之前,僅能查看Request相關(guān)的信息,同時(shí)在界面中Result列也顯示一個(gè)橫杠表示沒(méi)有收到Response,收到Response后會(huì)顯示實(shí)際的狀態(tài)碼。實(shí)際上Session的生命周期和之前講過(guò)的代理的原理是息息相關(guān)的,后續(xù)所有涉及到修改HTTP報(bào)文的操作都要對(duì)這個(gè)生命周期有深刻的認(rèn)識(shí)才能準(zhǔn)確的進(jìn)行。
SessionList中的表頭
SessionList的表頭區(qū)和大部分列表的功能一致,決定了各個(gè)內(nèi)容的顯示順序,在邊界拖動(dòng)可以更改顯示大小,點(diǎn)擊表頭還可以將所有內(nèi)容按照該列排序,我們先看看常見(jiàn)的表頭及其內(nèi)容含義:
#
顯示Session編號(hào)和當(dāng)前Session狀態(tài)/類型,編號(hào)是按照Request到達(dá)Fiddler的順序記錄的,清空全部后從新從1計(jì)數(shù),否則從當(dāng)前最大值開(kāi)始計(jì)數(shù),只要是經(jīng)過(guò)了Fiddler的流量均會(huì)被計(jì)數(shù),故部分被腳本隱藏的項(xiàng)會(huì)導(dǎo)致看起來(lái)列表中的編號(hào)不連貫,這并不會(huì)產(chǎn)生任何的問(wèn)題。編號(hào)是Fiddler賦予給每一個(gè)Session的,與客戶端和服務(wù)器的交互無(wú)關(guān)。
除了編號(hào)以外,每個(gè)Session還會(huì)匹配一個(gè)圖標(biāo)來(lái)標(biāo)示當(dāng)前session的狀態(tài)和類型,這里有一張表簡(jiǎn)述了各種狀態(tài)及其圖標(biāo):
Result
Result列顯示的是Response中的狀態(tài)碼,也就是HTTP協(xié)議中的Response Status Code。如前文所說(shuō)在沒(méi)有收到Response Header之前,這個(gè)項(xiàng)會(huì)用橫杠表示。常見(jiàn)的狀態(tài)碼如下:
- 200 OK:請(qǐng)求已成功,請(qǐng)求所希望的響應(yīng)頭或數(shù)據(jù)體將隨此響應(yīng)返回。
- 206 Partial Content:服務(wù)器已經(jīng)成功處理了部分 GET 請(qǐng)求。類似于 FlashGet 或者迅雷這類的 HTTP下載工具都是使用此類響應(yīng)實(shí)現(xiàn)斷點(diǎn)續(xù)傳或者將一個(gè)大文檔分解為多個(gè)下載段同時(shí)下載。
- 301 Moved Permanently:被請(qǐng)求的資源已永久移動(dòng)到新位置,新的永久性的URI 應(yīng)當(dāng)在響應(yīng)的 Location 域中返回。
- 302 Move temporarily:請(qǐng)求的資源臨時(shí)從不同的 URI響應(yīng)請(qǐng)求,新的永久性的URI 應(yīng)當(dāng)在響應(yīng)的 Location 域中返回。
- 304 Not Modified:304表明服務(wù)器根據(jù)請(qǐng)求判斷本地緩存無(wú)需更新,節(jié)省流量。
- 401 Unauthorized:需要提供身份認(rèn)證信息
- 403 Forbidden:服務(wù)器已經(jīng)理解請(qǐng)求,但是拒絕執(zhí)行它。與401響應(yīng)不同的是,身份驗(yàn)證并不能提供任何幫助。
- 404 Not Found:請(qǐng)求失敗,請(qǐng)求所希望得到的資源未被在服務(wù)器上發(fā)現(xiàn)。
- 407 Proxy Authentication Required:與401響應(yīng)類似,只不過(guò)客戶端必須在代理服務(wù)器上進(jìn)行身份驗(yàn)證。
- 500 Internal Server Error:服務(wù)器遇到了一個(gè)未曾預(yù)料的狀況,導(dǎo)致了它無(wú)法完成對(duì)請(qǐng)求的處理。一般來(lái)說(shuō),這個(gè)問(wèn)題都會(huì)在服務(wù)器端的源代碼出現(xiàn)錯(cuò)誤時(shí)出現(xiàn)。
- 502 Bad Gateway:作為網(wǎng)關(guān)或者代理工作的服務(wù)器嘗試執(zhí)行請(qǐng)求時(shí),從上游服務(wù)器接收到無(wú)效的響應(yīng)。
- 504 Gateway Timeout:作為網(wǎng)關(guān)或者代理工作的服務(wù)器嘗試執(zhí)行請(qǐng)求時(shí),未能及時(shí)從上游服務(wù)器(URI標(biāo)識(shí)出的服務(wù)器,例如HTTP、FTP、LDAP)或者輔助服務(wù)器(例如DNS)收到響應(yīng)。
Protocol
顯示當(dāng)前Session使用的Protocol類型,通常為HTTP或HTTPS。
Host
Host列顯示當(dāng)前訪問(wèn)網(wǎng)站的HOST,即“HTTP://”或“HTTPS://”與第一個(gè)“/”之間的部分,DNS根據(jù)HOST會(huì)把請(qǐng)求轉(zhuǎn)發(fā)給不同的IP地址。
URL
URL列顯示訪問(wèn)請(qǐng)求URL除HOST之外的部分
Body
Body列顯示ResponseBody的大小(字節(jié)為單位),這里的大小是僅包含ResponseBody的大小而不包含ResponseHeader,如果需要統(tǒng)計(jì)流量是需要把Header也計(jì)入的,我們可以通過(guò)自定義列的方法來(lái)實(shí)現(xiàn)這個(gè)需求,在后續(xù)幾期中會(huì)介紹,請(qǐng)持續(xù)關(guān)注哦。
Caching
Caching列顯示的是緩存相關(guān)的有效性信息,緩存實(shí)際上就是本地對(duì)服務(wù)器信息的存儲(chǔ),如果本地緩存是有效的,服務(wù)器就不用再傳輸一份已節(jié)省網(wǎng)絡(luò)流量,緩存的基本處理流程如下:
- 請(qǐng)求處理:用戶發(fā)起一個(gè)http請(qǐng)求,緩存獲取到URL,根據(jù)URL查找是否有匹配的副本,這個(gè)副本可能在內(nèi)存中,也可能在本地磁盤。
- 新鮮度檢測(cè):如果緩存中存在所請(qǐng)求資源的副本,則進(jìn)行新鮮度檢測(cè)。新鮮度檢測(cè)舉個(gè)簡(jiǎn)單的例子,我們?cè)谏痰曩I了一瓶汽水,汽水瓶上肯定會(huì)標(biāo)有過(guò)期時(shí)間,我們會(huì)根據(jù)這個(gè)過(guò)期時(shí)間和現(xiàn)在的時(shí)間做對(duì)比,看看飲料過(guò)期了沒(méi),如果沒(méi)過(guò)期,我們正常喝就行了,如果已經(jīng)過(guò)期,我們肯定要找商家。。。其實(shí)這就是一個(gè)新鮮度檢測(cè)的過(guò)程,HTTP請(qǐng)求的新鮮度檢測(cè)流程也是這樣的,HTTP發(fā)起一個(gè)請(qǐng)求時(shí),發(fā)現(xiàn)緩存中有相應(yīng)的副本,接著就會(huì)檢查這個(gè)副本有沒(méi)有過(guò)期,如果沒(méi)有過(guò)期,直接使用。如果已經(jīng)過(guò)期,則進(jìn)行再驗(yàn)證。具體的實(shí)現(xiàn)在下面會(huì)介紹。
- 服務(wù)器再驗(yàn)證:緩存中的文檔過(guò)期了并不代表他和服務(wù)器上的不一樣,所以這個(gè)時(shí)候就需要問(wèn)問(wèn)服務(wù)器,過(guò)期的這段時(shí)間里這個(gè)文檔到底有沒(méi)有改變。如果改變了,緩存就會(huì)獲取一份新的文檔副本,然后發(fā)送給客戶端。如果沒(méi)有改變,緩存只需要獲取新的首部,包括一個(gè)新的過(guò)期時(shí)間,并對(duì)緩存中的首部更新。
- 創(chuàng)建響應(yīng)并返回:我們希望緩存看起來(lái)就像是來(lái)自原始服務(wù)器一樣,緩存將已緩存的服務(wù)器響應(yīng)首部作為響應(yīng)首部,發(fā)送給客戶端。
簡(jiǎn)單了解下服務(wù)器再驗(yàn)證的實(shí)現(xiàn):緩存要問(wèn)問(wèn)服務(wù)器,牛奶已經(jīng)過(guò)期了,到底還能不能喝。我說(shuō)錯(cuò)了,是文檔,不是牛奶。HTTP中,使用兩個(gè)請(qǐng)求請(qǐng)首部來(lái)完成這個(gè)功能:If-Modified-Sice和If-None-Match。為啥又要兩個(gè)首部來(lái)完成這個(gè)功能了?答案還是因?yàn)闅v史的原因。一開(kāi)始使用 If-Modified-Sice:<date>首部,date是上一次緩存牛奶時(shí),響應(yīng)中Last-Modified首部的值。客戶端拿著這個(gè)值,問(wèn)服務(wù)器,這段時(shí)間內(nèi)這個(gè)牛奶你有沒(méi)有修改過(guò)?服務(wù)器看了看這個(gè)牛奶的修改時(shí)間,如果沒(méi)有修改過(guò),會(huì)返回一個(gè)304 Not Modified的響應(yīng);如果修改過(guò),把最新的牛奶返回給客戶端。后來(lái),人們發(fā)現(xiàn)這樣有問(wèn)題,因?yàn)榫退阈薷臅r(shí)間變化了,文檔也不一定發(fā)生改變!于是乎,就有了 If-None-Match:<tag>首部,tag是上一次緩存文檔時(shí),響應(yīng)中Etag的值,Etag是一種唯一標(biāo)識(shí)資源的方式,就像java中的hashcode,如果hashcode不一樣,那么兩個(gè)對(duì)象肯定不一樣!
緩存部分內(nèi)容節(jié)選自HTTP協(xié)議:緩存,作者:夕水溪下
Content-Type
Content-Type是ResponseHeader中的一個(gè)關(guān)鍵字段,用來(lái)標(biāo)示該Response的類型,客戶端在收到Response后可以根據(jù)不同的類型做不同的處理。
Process
Process列顯示觸發(fā)該請(qǐng)求的進(jìn)程,僅對(duì)PC機(jī)的流量生效,遠(yuǎn)程代理流量是無(wú)法顯示進(jìn)程信息的
Remark
Remark列顯示用戶對(duì)該Session做的備注,主要用于將給他人展示時(shí)使用,點(diǎn)擊快捷工具欄中的Remark可以快速添加備注信息
SessionList的上下文菜單
上下文菜單即鼠標(biāo)右鍵菜單,在選中一條或若干條Session記錄后(Ctrl可間隔選中,Shift可以選中一片,空白區(qū)域拖動(dòng)也可完成選中操作),右鍵可以打開(kāi),菜單是可以通過(guò)FiddlerScript擴(kuò)展的,或者隨版本變化,可能造成每個(gè)人的上下文菜單不盡相同,我們來(lái)看看他們的用途:
- Decode Selected Sessions:解碼選中的Sessions
- AutoScroll Session List:開(kāi)啟/關(guān)閉自動(dòng)滾動(dòng)
- Copy:復(fù)制選中的Sessions,有子選項(xiàng):
- Just Url:復(fù)制當(dāng)前Session的URL
- This column:復(fù)制當(dāng)前Session鼠標(biāo)點(diǎn)擊列的內(nèi)容
- Terse summary:復(fù)制Request的Method和URL,以及Response的狀態(tài)碼(如果是301或302還會(huì)列出目標(biāo)Location)
- Headers only:以文本復(fù)制Request和Response的Header部分
- Session:以文本復(fù)制Request和Response的全部?jī)?nèi)容
- Full Summary:復(fù)制當(dāng)前顯示的所有列的信息
- Save:保存選中的Sessions,有子選項(xiàng):
- Selected Sessions:針對(duì)所有選中項(xiàng)的操作,有子選項(xiàng):
- in ArchiveZIP:使用自帶的saz格式保存選中的請(qǐng)求,可以用于回放(在File->Load Achieve中可以load保存的saz文件)
- as Text…:以文本格式保存選中的請(qǐng)求
- as Text(Header Only):以文本格式保存選中的請(qǐng)求(僅保留Header不保存正文)
- Request:針對(duì)選中Session的Request的保存操作,有子選項(xiàng):
- Entire Request…:保存完整的Request
- Request Body…:僅保存正文部分(注:通常只有POST請(qǐng)求才會(huì)帶有正文部分,GET請(qǐng)求只有URL而無(wú)正文)
- Response:針對(duì)選中Session的Response的保存操作,有子選項(xiàng):
- Entire Response…:保存完整的Response
- Response Body…:僅保存正文部分(即服務(wù)器返回的內(nèi)容),這里重申下這兩個(gè)選項(xiàng)在Response中的區(qū)別,Entire Response在Response Body之外還包含了狀態(tài)碼和Headers等其他信息,可以視不同的需要進(jìn)行選擇。
- …And Open as Local File:將所有選中的Session依次保存并用文本編輯器打開(kāi)。
- Selected Sessions:針對(duì)所有選中項(xiàng)的操作,有子選項(xiàng):
- Remove:刪除指定的Sessions,有子選項(xiàng),字面意思很簡(jiǎn)單,不翻譯了:
- Selected Sessions:
- Unselected Sessions:
- All Session:
- Filter Now:在當(dāng)前列表中使用過(guò)濾器清除掉指定條件的Sessions,被過(guò)濾的Sessions無(wú)法重新顯示,右鍵點(diǎn)擊狀態(tài)欄上方的過(guò)濾項(xiàng)可以取消該項(xiàng)的過(guò)濾
- Comment:針對(duì)當(dāng)前Session添加備注
- Mark:將選中Sessions做各種顏色的標(biāo)注
- Replay:回放選中的請(qǐng)求,有子選項(xiàng)供各種不同的回放方式選擇:
- Reissue Requests:重新回放該請(qǐng)求(回放是由Fiddler觸發(fā)的,而不是客戶端程序發(fā)起的)
- Reissue Unconditionally:無(wú)條件回放,和前一項(xiàng)的區(qū)別是不會(huì)發(fā)送If-Modified-Since或If-None-Match的Header,所以服務(wù)器不會(huì)返回304而是正常返回資源。
- Reissue and Edit:編輯后回放請(qǐng)求,會(huì)重新請(qǐng)求并生成上行斷點(diǎn),可以在Inspectors中編輯請(qǐng)求相關(guān)信息,后續(xù)介紹斷點(diǎn)和Inspectors時(shí)會(huì)詳細(xì)介紹。
- Revisit in IE:在IE中請(qǐng)求該請(qǐng)求
- Select:按照條件選擇指定的Sessions,有子選項(xiàng):
- Parent Request:選擇父Session,通常會(huì)選擇Reffer Header指向的URL
- Child Requests:選擇子Session,通常會(huì)選擇Location Header指向的URL
- Duplicate Requests:選擇重復(fù)的請(qǐng)求
- Matching Values:選擇與該列重復(fù)的Sessions(根據(jù)右鍵選擇的不同的列會(huì)有不同選擇結(jié)果)
SessionList中常用的快捷鍵
下面來(lái)整理下使用過(guò)程中會(huì)經(jīng)常接觸到的快捷鍵:
快捷鍵 | 對(duì)應(yīng)操作 |
---|---|
空格 | 選中焦點(diǎn)Session |
CTRL+A | 全選Sessions |
ESC | 取消Session的選擇 |
CTRL+I | 反選 |
CTRL+X | 刪除全部Session |
Delete | 刪除選中的Sessions |
Shift+Delete | 刪除未選中的Sessions |
R | 重新觸發(fā)當(dāng)前的請(qǐng)求 |
Shift+R | 重新觸發(fā)當(dāng)前的請(qǐng)求若干次(所有Reissue類的快捷鍵都可以和Shift配合,比如E,U,V) |
U | 無(wú)條件重新觸發(fā)當(dāng)前請(qǐng)求,忽略本地緩存信息 |
E | 編輯后重新觸發(fā)當(dāng)前請(qǐng)求 |
P | 定位到當(dāng)前請(qǐng)求的父請(qǐng)求(通過(guò)Referer Header決定) |
C | 定位到當(dāng)前請(qǐng)求的子請(qǐng)求(通過(guò)Referer Header或者重定向Location決定 Header) |
D | 選中全部有相同URL,Method,Status Code的Sessions |
ALT+回車 | 查看當(dāng)前Session的屬性(盡在選中一個(gè)Session時(shí)有效) |
Shift+回車 | 在新的窗口中查看當(dāng)前Session的觀察器 |
Backspace | 選中上一次選中的Session |
Insert | 標(biāo)記當(dāng)前Session紅色字體加粗 |
CTRL+1到CTRL+6 | 各種標(biāo)記顏色 |
M | 針對(duì)當(dāng)前Session添加Comment |
Alt+鼠標(biāo)單擊 | 選中全部和當(dāng)前列一致的Sessions |
F2 | 解鎖為可編輯狀態(tài)(具體使用在后續(xù)Inspectors章節(jié)中介紹) |
Ctrl+U | 復(fù)制當(dāng)前Session的URL部分 |