一文搞定前端代理騷操作!再也不怕線上bug啦!
徐帥武,微醫(yī)云服務團隊前端工程師。一個熱衷于周末“搞事情”的前端程序猿

前言
為什么我們需要一個代理工具?一個靈活好用的代理工具對開發(fā)的作用有多大?
一個順手的代理工具,可以讓我們隨心所欲的掌控我們的開發(fā)環(huán)境,當前環(huán)境前置服務掛了還要等重啟?不!直接切一個可用環(huán)境接著我的開發(fā)。驗證頁面不同數(shù)據(jù)狀態(tài)的流程還要造數(shù)據(jù)?不!直接代理修改數(shù)據(jù)走流程,省勁。特定機型線上問題抓耳撓腮不知如何定位?代理連上查看元素、遠程 log 輕松定位問題所在......
使用代理不說能解決所有問題,但是至少可以在解決問題的流程上幫我們省大半的時間,而不是碰到環(huán)境問題就在那兒等重啟
Whistle 介紹
關于 Whistle 下面引用官方的
Whistle(讀音[?w?s?l],拼音[wēisǒu])基于 Node 實現(xiàn)的跨平臺 web 調(diào)試代理工具,類似的工具有 Windows 平臺上的 Fiddler,主要用于查看、修改 HTTP、HTTPS、Websocket 的請求、響應,也可以作為 HTTP 代理服務器使用,不同于 Fiddler 通過斷點修改請求響應的方式,Whistle 采用的是類似配置系統(tǒng) hosts 的方式,一切操作都可以通過配置實現(xiàn),支持域名、路徑、正則表達式、通配符、通配路徑等多種匹配方式,且可以通過 Node 模塊擴展功能
與 Charles 對比
想必大部分人剛開始接觸抓包代理的時候用的都是 Charles 和 Fiddler 這兩個老牌抓包代理工具之一,筆者當初就是 Charles 入的門。但是后面了解到 Whistle 之后就毅然選擇投入了它的懷抱。下面說一下筆者認為 Whistle 的幾大優(yōu)勢。
開源免費,相比 Charles 的收費,開源的 Whistle 使用起來當然是更加的沒有負擔。 易于安裝,Whistle 基于 Node 實現(xiàn),安裝就是全局安裝 npm 包,對于前端來說當然是更加的友好。 配置集中靈活,Whistle 的各種功能都使用配置文件的方式集中管理,查看和修改都更加友好且易于分享。 自由可編程,當內(nèi)置功能都不能滿足需求時,還可以使用 Npm 包的方式開發(fā)插件對于 JS 開發(fā)者來說更加的友好易用。
如何使用
安裝和使用
因為是 npm 包,所以安裝只需要一句話(Mac 或 Linux 的非 root 用戶需要在命令行前面加 sudo,如:sudo npm install -g whistle)
#?安裝
npm?install?-g?whistle
#?啟動
w2?start
#?重啟
w2?restart
#?停止
w2?stop
訪問主界面
一般情況下直接訪問http://localhost:8899/#network這個地址即可,不使用默認端口的話,改為啟動的端口號訪問即可。界面如下:
配置代理
配置信息
代理服務器:127.0.0.1 (如果部署在遠程服務器或虛擬機上,改成對應服務器或虛擬機的 ip 即可)
默認端口:8899 (如果端口被占用,可以在啟動時通過 -p 來指定新的端口,更多信息可以通過執(zhí)行命令行 w2 help (v0.7.0 及以上版本也可以使用 w2 help) 查看)
由于 Whistle 不能自動設置系統(tǒng)代理,所以需要代理的內(nèi)容需要手動配置
系統(tǒng)代理
這個不常用,各個系統(tǒng)設置系統(tǒng)代理方式不同,可自行查找設置方式
瀏覽器代理(Chrome 為例)
雖然 Chrome 也可以設置代理,但是更推薦使用SwitchyOmega插件進行代理的管理,可以同時配置梯子的代理規(guī)則,不至于開了代理就不能訪問 Google 了
移動端代理
移動端代理需要兩個設備在同一 WiFi 下(網(wǎng)絡互通),在設置中配置當前 Wi-Fi 的代理,以 iOS 為例:代理服務器為啟動 Whistles 設備的 IP
https 證書
會配置或沒有 https 需求的可跳過這一段。
https 默認時不能查看其內(nèi)容的我們需要安裝自定義的根證書來進行 https 請求的查看,這部分內(nèi)容沒有什么特別的下面就直接把文檔上的內(nèi)容復制過來了。
下載根證書,開啟捕獲 HTTPS 請求:
安裝根證書
證書按下面步驟安裝后,如果還出現(xiàn)安全提醒,這個主要原因是之前你訪問過該頁面,導致長連接已建立,可以等段時間再訪問、或重新打開瀏覽器,或重啟下 Whistle:w2 restart
如上圖下載完根證書后點擊 rootCA.crt 文件,彈出根證書安裝對話框。
Windows:
Installing a root certificate on Windows

下載證書后,雙擊證書,根據(jù)指引安裝證書。證書安裝過程,要確保證書存儲到受信任的根證書頒發(fā)機構下。
Mac:
Mac 安裝證書后,需要手動信任證書,步驟如下:

打開證書管理界面,找到帶有 whistle 的字樣的證書,如果有多個又不確定最新安裝的是哪個,可以全部刪除后重新安裝

雙擊證書后,點擊 Trust 左邊展開選項,紅色部分選擇 Always Trust (總是信任),點擊左上角關閉當前界面會要求輸入密碼;輸入密碼后可 以看到證書上面紅色的圖標 x 不見了,到這一步說明完成證書安裝。

Firefox:
菜單 > 首選項 > 高級 > 證書 > 證書機構 > 導入 -> 選中所有 checkbox -> 確定
iOS
手機設置代理后,Safari 地址欄輸入 rootca.pro,按提示安裝證書(或者通過 whistle 控制臺的二維碼掃碼安裝,iOS 安裝根證書需要到連接遠程服務器進行驗證,需要暫時把 Https 攔截功能關掉) iOS 10.3 之后需要手動信任自定義根證書,設置路徑:Settings > General > About > Certificate Trust Testings 具體可以看這里
Android
whistle 控制臺二維碼掃碼安裝,或者瀏覽器地址欄 rootca.pro 按提示安裝 部分瀏覽器不會自動識別 ca 證書,可以通過 Android Chrome 來完成安裝 android 6.0 之后的一些 app 在成功安裝證書后仍然無法對 https 連接進行手抓包,有可能是該 app 沒有添加信任用戶自定義證書的權限。請確認該 app 是否有如下配置:
<base-config?cleartextTrafficPermitted="true">
???<trust-anchors>
???????<certificates?src="system"?/>
???????<certificates?src="user"?/>
???trust-anchors>
base-config>
這主要是因為 android 6.0 之后的版本默認配置發(fā)生了變化,更多請看 Android 開發(fā)文檔。
開啟攔截 HTTPS
圖中的打開的對話框有個 checkbox:
1.Capture HTTPS CONNECTs:開啟 Https 攔截功能,只有勾上這個 checkbox 及裝好根證書,Whistle 才能看到 HTTPS、Websocket 的請求
自定義請求證書或根證書
whistle 會自動生成根證書,并根據(jù)根證書對每個請求動態(tài)生成 https 證書,如果需要用自定義的證書,甚至根證書,可以有兩種方式(只支持 .crt 格式的證書):
把普通證書對 (如:test.crt 和 test.key、test2.crt 和 test2.key 等等) 或根證書 (名字必須為 root.crt 和 root.key),放在系統(tǒng)的某個目錄,如 /data/ssl,并在啟動時添加啟動參數(shù) w2 start -z /data/ssl ,whistle 會自動加里面的證書 (v1.14.8 及以上版本支持) 把上述證書或根證書放在固定目錄 ~/.WhistleAppData/custom_certs/里面,whistle 會自動加里面的證書
優(yōu)先級 -z dir > ~/.WhistleAppData/ > 內(nèi)置證書
匹配規(guī)則
Whistle 的匹配規(guī)則非常的多,這里介紹幾種常用的匹配模式基本可以覆蓋 90%的使用場景。詳細規(guī)則可以查看【匹配規(guī)則】
注: 默認匹配規(guī)則都是下面這種形式:pattern operatorURI,匹配規(guī)則在左,操作規(guī)則在右。
域名匹配
#?匹配域名?www.test.com?下的所有請求,包括?http、https、ws、wss,tunnel
www.test.com?operatorURI
#?匹配域名?www.test.com?下的所有?http?請求
http://www.test.com?operatorURI
#?匹配域名?www.test.com?下的所有?https?請求
https://www.test.com?operatorURI
#?上述匹配也可以限定域名的端口號
www.test.com:8888?operatorURI?#?8888?端口
www.test.com/?operatorURI?#?http?為?80?端口,其它?443?端口
路徑匹配
#?限定請求協(xié)議,只能匹配?http?請求
http://www.test.com/xxx?operatorURI
http://www.test.com:8080/xxx?operatorURI
#?匹配指定路徑下的所有請求
www.test.com/xxx?operatorURI
www.test.com:8080/xxx?operatorURI
通配符匹配
通配符匹配以 ^ 開頭,* 為通配符,可以通過 9 匹配通配符匹配的分組,$0 表示整個 URL。
#?通配符匹配必須以?^?開頭
#?訪問?wy.guahao.com/abc/xyz/1.js?就會被映射到?/path/to/xyz/1.js
^wy.guahao.com/abc/***???/path/to/$1
#?也可以用?$?限制結尾
#?只轉(zhuǎn)發(fā)?index.js?結尾的?url
^wy.guahao.com/abc/***index.js$???/path/to/$1
* 表示匹配到一個 / 就停下,而 *** 表示匹配多個
域名通配符
在域名中使用 * 不需要用 ^ 開頭,例如我們用*.com operatorURI時就是匹配 guahao.com 等,但是不匹配 www.guahao.com。而想要對所有子域名生效,可以用***.com operatorURI這樣可以匹配 wx.wy.guahao.com 這樣的域名
正則匹配
對于非常靈活的匹配規(guī)則,可以使用正則匹配。
#?匹配所有請求
/./?operatorURI
#?匹配?url?里面包含多個關鍵字的請求
/keyword/?operatorURI
#?通過正則匹配,同樣的?$1~$9?捕獲分組,$0?表示整個?URL
/(\d+).html/?operatorURI
常用功能
綁定 Host
和 Host 文件寫法相同,走代理的時候不會再查詢本機的 Host 文件,修改這個 Host 配置沒有緩存,立即生效
127.0.0.1?wy.guahao.com
替換請求
調(diào)試一些有域名校驗難以在本地查找的問題時(比如微信授權,微信 SDK 調(diào)用),可以將線上的頁面代理到本地開發(fā)環(huán)境來進行問題排查。
針對一些非 Webpack 編譯的資源可以將線上資源替換,達到直接調(diào)試線上的效果。前后端不分離的項目,本地環(huán)境難以配置時,可以在測試環(huán)境調(diào)試本地的 JS、CSS 文件。
#?本地替換線上
127.0.0.1?wya.guahao.com
https://wy.guahao.com?http://wya.guahao.com:8080
#?代理替換資源
^http://test.guahao-test.com/front/hps-h5-static/css/h5.min.css***?http://127.0.0.1:9091/front/hps-h5-static/css/h5.css
^http://test.guahao-test.com/front/hps-h5-static/js/h5.js***?http://127.0.0.1:9091/front/hps-h5-static/js/h5.js
替換返回內(nèi)容
文本類請求 append 內(nèi)容、替換返回內(nèi)容
#?說明:會把內(nèi)容 append 到請求后面
http://guahao.com/style.css?resAppend://{myAppend.css}
#?說明:完全替換請求內(nèi)容
http://guahao.com/style.css?resBody://{myResBody.css}
注入 JS 腳本
線上項目我們一般不會啟用 vConsole,Eruda 之類的調(diào)試工具。出現(xiàn)問題時難以查看報錯與其他信息。這時可以使用代理將 vConsole,Eruda 注入到頁面中來查看問題。
#?htmlAppend?操作即為在?html?部分最后注入?debugger?變量,變量內(nèi)容在“Value”面板進行設置
https://wy.guahao.com/?htmlAppend://{debugger}
debugger 變量的內(nèi)容:
<script?crossorigin="anonymous"?integrity="sha384-ltIfi6+efoMR4xY0cwhn9a243JE/09cby6RJioKuqFKzs4un/eTmCLbAGaVM8xsJ"?src="https://lib.baomitu.com/eruda/2.2.1/eruda.js">script>
<script>eruda.init();script>


遠程 Console.xxx 輸出
移動端調(diào)試的時候的痛點就是不能查看 log,及時我們用了上面的方法向頁面注入 Eruda 之類的調(diào)試工具,也免不了兩個設備來回切換的查看內(nèi)容。Whistle 內(nèi)部實現(xiàn)了類似瀏覽器的 Console 的遠程 Log 平臺,使用對應的規(guī)則就可以在 PC 端進行其他設備上 log 的查看
#?wy.guahao.com?域名的網(wǎng)站遠程打印?log
#?wy.guahao.com?log://
#?遠程打印?log?同時注入腳本
wy.guahao.com?log://{injection-log}
#?---------?Value?部分?------------
#?injection-log?內(nèi)容
console.log('-----------------start-------------------')
console.log('遠程?log')
console.log('查看某個變量',?window)
console.log('-----------------end---------------------')

集成 weinre 遠程調(diào)試
Weinre 是 Apache 基礎工程之一,是 WEb INspector REmote 的縮寫。正如其名,它是和 Firebug 或瀏覽器調(diào)試工具類似,但是能夠在遠程運行調(diào)試 web 頁面。所以如果你使用過火狐開發(fā)者工具或 Chrome 的調(diào)試工具,那么上手 Weinre 就會非常容易,非常自然。
但是使用 Weinre 的配置十分繁瑣,Whistle 可以自動幫我們在頁面注入 Weinre 的啟動腳本,使我們使用 Weinre 變成了一句話的事情。
#?集成?weinre?的功能,?key?為任意的字符串,主要用于區(qū)分頁面
wy.guahao.com?weinre://[key]

小結
上面就是開發(fā)過程中筆者常用的幾個功能,Whistle 的功能遠不止此。有興趣的可以去 Whistle 文檔查看詳細內(nèi)容,下面是它協(xié)議列表的一部分,可以看出功能非常的豐富。而且支持插件的編寫,有自定義需求時還可以自己編寫插件來實現(xiàn)所需的功能。
最后
如果你覺得這篇內(nèi)容對你挺有啟發(fā),我想邀請你幫我三個小忙:
點個「在看」,讓更多的人也能看到這篇內(nèi)容(喜歡不點在看,都是耍流氓 -_-)
歡迎加我微信「qianyu443033099」拉你進技術群,長期交流學習...
關注公眾號「前端下午茶」,持續(xù)為你推送精選好文,也可以加我為好友,隨時聊騷。


