web除錯代理工具是web開發人員必備的工具,它在發起web請求的客戶端與伺服器之間充當中間人角色,可以用於檢視、修改或替換HTTP、HTTPS、Websocket請求(響應)資料,協助我們做本地開發除錯、構造資料、定位問題等等,業界已有一些比較優秀的web除錯代理工具,特別是Windows上的Fiddler,由於其出色的功能設計,儼然成為了web除錯代理工具的代名詞。但Fiddler只能在Windows系統上使用,當我們換上Mac或者開發環境限制必須使用Linux時,我們很難在這些平臺上找到類似Fiddler的工具,這個時候可能被提起最多的是Charles,Charles是用Java實現的跨平臺web除錯代理工具,理論上可以在安裝java虛擬機器的桌面系統上使用,用過Fiddler的人普遍覺得Charles難用,不管是效能、體驗、介面都無法跟Fiddler相提並論(事實上Fiddler本身也是很耗記憶體),更重要的是Charles不是免費的,價格也不菲,這也可能是因為在Mac、Linux平臺上可以選擇的web除錯代理工具也不多,下面我要給大家詳細介紹的是本文的主角,開源免費且持續在維護的whistle–全新的跨平臺web除錯代理工具。
Note: 想了解除錯代理工具的原理可以看這篇文章:HTTP 代理原理及實現。
whistle
Github: https://github.com/avwo/whistle
whistle是用NodeJS實現的跨平臺web除錯代理工具,可以安裝部署在裝有NodeJS的作業系統上(包括Windows、Mac、Linux等桌面或命令列系統),並可以通過Chrome瀏覽器訪問本地或遠端whistle的管理配置介面:
-
檢視、修改或替換HTTP、HTTPS、Websocket請求(響應)資料(包括url,host,方法,狀態碼,頭部及內容等)
-
設定延遲請求(響應)
-
限制請求(響應)速度
-
在Composer裡面構造請求
-
可以把請求代理到其它伺服器(支援socks和http代理)
-
檢視請求列表的Timeline
-
檢視頁面JS指令碼執行過程中丟擲的異常(可以用在除錯終端頁面或遠端除錯)
-
檢視JS中的
console[info, log, warn, error, fatal]
(這些方法在IE也可以使用)列印出來的資料物件(可以用在除錯終端頁面或遠端除錯) -
利用whistle整合的
weinre
檢視或修改頁面的DOM結構(可以用在除錯終端頁面或遠端除錯) -
使用通過外掛的形式擴充套件的功能(外掛可以用來擴充套件whistle的功能,特別是整合本地開發環境,方便開發人員使用),如:處理combo請求
whistle借鑑了Fiddler的一些優秀的設計,比如請求列表及其詳細內容的展示(即Network),但whistle不是Fiddler的複製品,除了請求列表的展示外,whistle在操作請求及功能擴充套件上有著自己獨特的方式,讓修改請求(響應)操作變得更簡單,並整合了終端(遠端)除錯工具。
Note:為了讓大家能對下面內容更好的理解及快速上手whistle,請先按步驟安裝好whistle:安裝node、安裝whistle、配置代理、啟動whistle
規則原理
Fiddler修改請求(響應)的資料時,需要對每個請求設定斷點後–>手動修改–>手動放開請求,如果是同時修改多個請求或者多次修改某個請求時,體驗不是很好;而whistle把對請求(響應)的操作分類,每一類對應一種協議(如:替換本地檔案 file://
),每個具體操作要用到的引數值放到協議後(如:file:///User/xxx/test.html
中的/User/xxx/test.html
),這樣whistle把每個操作抽象成一個uri
。
問題來了,如果引數值有空格或需要多個引數(比如修改頭部的一些欄位),這個whistle是怎麼處理的?
上述問題包含兩個問題:
-
如何引數值有空格的問題?
在單引數情形下,如果是檔案路徑或者是下面第二個問題要提到的請求引數型別(如:file://filepath
、resAppend://filepath
、reqHeaders://test=a%20b&referer=test
等),可以用%20
來代替,其它情形,可以用{key}
的形式把引數值存到whistle的Values系統,如:ua://{chrome-ua}
,whistle會自動到Values裡面找chrome-ua
對應的值。 -
如何處理多個引數的情形?
為方便使用者使用,whistle儘可能把一些常用的操作精簡到只有一個引數的情形(如請求頭部欄位,可以用協議req
這種多引數的形式來新增或修改,對裡面常用的欄位,如referer
、ua
等也可以用獨立的協議(referer
、ua
)來設定),但不可能把把所有操作都抽象成單個引數的情形。對於多引數情形,有如下3種方式:
上面解決了把每個對web請求的操作用一個uri
來表示的問題, 現在我們把對web請求的操作都可以抽象成一個operator-uri
,如何用這些operator-uri
來操作具體請求呢?
處理這個問題,whistle擴充套件了傳統hosts配置方式,採用匹配請求url到operator-uri
的對映:
pattern operator-uri
pattern可以以下三種方式:
-
域名匹配:
www.example.com operator-uri
-
路徑匹配:
www.example.com/... operator-uri
-
正則匹配:
/example/ operator-uri
為了相容hosts的配置方式:
# 單個匹配
127.0.0.1 www.example.com
# 多個匹配
127.0.0.1 www.example1.com www.example2.com www.exampleN.com
whistle預設匹配順序是從上到下,從左到右,多個匹配也可以寫成
# 多個匹配
pattern operator-uri1 operator-uri2 operator-uriN
如果whistle可以判斷operator-uri
不可能為web請求的url,即不是如下uri
形式:
# operator-uri協議為http, https, ws, wss之一
pattern http://xxxx
# operator-uri不包含協議,又不是ip
pattern xxxxx
或者pattern為正規表示式,滿足這兩種情況下,pattern
和operator-uri
的順序是可以調換的:
# 單個匹配
operator-uri pattern
# 多個匹配的情況
operator-uri pattern1 pattern2 patternN
上面講了Rules的一些配置規則原理及Values的用途,包括:operator-uri
設計原理,規則的匹配順序(從上到下,從左到右),匹配方式,什麼情況下可以對調等等。
一些例子
下面舉一些例子,讓大家快速上手whistle(規則中用#
作為註釋符號,如果要檢視或修改HTTPS、Websocket的請求(響應)資料,要開啟HTTPS攔截功能:啟用HTTPS):
-
host
host的配置方式不僅完全相容系統自帶的配置方式,而且支援路徑、正則匹配:# 傳統的配置方式 # 單個匹配 127.0.0.1 www.ifeng.com # 多個匹配 127.0.0.1 www.ifeng.com www.qq.com # 路徑(順序可以調換) # 單個匹配 127.0.0.1 http://www.ifeng.com/xxx # 多個匹配 127.0.0.1 http://www.ifeng.com www.qq.com/xxx #正則(順序可以調換) # 單個匹配 127.0.0.1 /ifeng/ # 多個匹配 127.0.0.1 /ifeng/ /qq/ # whistle也支援如下方式,在ip前面加個協議(順序可以調換) # 單個匹配 host://127.0.0.1 www.ifeng.com # 多個匹配 host://127.0.0.1 www.ifeng.com www.qq.com
-
埠對映(下面舉得例子都是用域名匹配的方式,其它方式同理)
# 本地除錯 www.example.com 127.0.0.1:8080 # 對映到線上 www.example.com www.qq.com www.example.com:8080 www.qq.com
-
本地替換
# 下面用`|`來分隔目錄或檔案,從左到右依次找到存在的檔案為止 www.example.com file:///User/xxx/test|/User/xxx/test/index.html
上述配置,如果我們訪問http://www.example.com/
,則whistle會先找是否有/User/xxx/test
這個檔案,如果沒有就會匹配/User/xxx/test/index.html
;如果我們訪問http://www.example.com/test.html
,則whistle會先在找檔案/User/xxx/test/test.html
,再找/User/xxx/test/index.html/test.html
,如果沒就返回404
。
這裡只是舉了幾個小例子,whistle還有非常多的功能,如:reqHeaders
,resHeaders
,log
,disable
,filter
,weinre
等等,而且還支援外掛擴充套件,更多功能請參考:Wiki,功能列表
後續規劃
whistle是我業餘時間在維護且會長期維護的專案,一般來說新版本(如果有)的釋出放在週日晚上(修復影響功能的bug的版本不受時間限制,有新版本釋出介面中的About選單現會有紅點提醒或者大版本釋出則是直接彈框提醒,大家按提示更新就可以),下面是一些後面的規劃內容:
-
外掛whistle.websocket開發:用於檢視websocket的請求內容
-
外掛whistle.img開發:用於檢視抓包到的圖片內容
-
外掛whistle.settings開發:用於一鍵安裝系統代理及安裝根證照(如果根證照不能一鍵安裝,至少要做到點選能彈出根證照的安裝對話方塊),也為後面的客戶端版本做準備
-
whistle的客戶端開發:有打算把一些自動化測試的功能整合進來,設想的互動功能也會比Node強很多,因為可以直接操作本地檔案
-
官網http://wproxy.org及文件建設:打算用Gitbook把文件重新整理,然後再i18n下及官網陸續建立起來
上面面規劃的功能都只是在業餘時間做,所以不能給出確切的完成時間,前面兩個外掛會盡快開發出來,想關注進度可以 Follow me:https://github.com/avwo。
PS:為什麼不把websocket、img、settings這幾個外掛功能整合到whistle裡面,而要以外掛的形式單獨存在?主要是考慮到這幾部分功能用到的時候相對比較少,及減少安裝whistle過程中出現錯誤及執行過程中的記憶體問題,像處理websocket用到的中介軟體體積比較大且需要本地編譯,img功能有比較耗記憶體和硬碟,而且把這部分功能放在獨立的頁面可能體驗更好,綜上考慮沒有把這部分功能整合到whistle裡面,但後續的客戶端版本會直接整合進來。