為什么需要網絡攔截工具
通常我們會遇到這樣的場景:
- 線上一個圖片有異常,線下修正之后需要發布之前進行測試,有些情況下,QA同學有直接在線上環境測試的需求,只是鏈接本地資源,通常在windows下有一個很好的工具fiddler可以完成這個功能,當然mac下也有其對應的工具Charles,但是工具收費,在不付費的前提下,使用體驗很差。
- 線上js資源出了bug,線下修復之后通過測試區不好還原場景,因為只有在線上的數據環境下才能重現bug,但是在線上的代碼一般都是混淆過的,調試很不友好(這里不考慮生成soucemap的場景)
- 其它需要使用本地資源替換線上資源的情況
flyover是什么
- flyover是一個簡易的本地網絡代理工具,基於Puppteer做網絡攔截,可以實現對線上壓縮代碼的調試。
- flyover基於node & puppeteer實現 & 代碼開源(當然發布沒幾天,可能會有很多問題,歡迎大家issue)
如何使用flyover
- npm install -g flyover
- flyover --help具體細節見
https://github.com/JerrZhang/flyover ,歡迎issue 和 star
flyover 實現原理
我們知道所有請求,無論是頁面請求還是js 發起的各種請求,最終都是通過瀏覽器軟件發起的,服務器響應后,都是響應給瀏覽器的,那么整個工程可以細分為如下流程(個人理解):
- 請求瀏覽器發起請求
- 瀏覽器接到請求申請,發起請求到服務器
- 服務器處理后響應給瀏覽器
- 瀏覽器把響應給上層引擎(比如UI引擎& js引擎等)
puppeteer提供了在第2階段和第4個階段的攔截,可以完成瀏覽器接到請求之后,終端到遠程服務器的請求,轉而讀取本地資源響應給上層引擎;依次來實現對資源的本地化攔截和替換;技術實現也比較簡單,只需要在啟用攔截后,監聽page 對象的request事件進行處理即可,核心代碼如下:
//啟用請求攔截
this.page.setRequestInterception(true);
//監聽請求事件
this.page.on('request', (req) => {
//如果包含在拒絕列表中的文件
let denyFile = this._isInCtrllist(req.url(), ctrlsfiles);
if (denyFile.getIsDenyFile()) {
//直接響應本地文件內容
req.respond({
body: denyFile.getFileContent()
});
} else {
//其它情況請求繼續
req.continue();
}
})
簡單的幾行代碼就實現了一個初級的網絡攔截工具,是不是很簡單實用?
完整代碼 https://github.com/JerrZhang/flyover
不足
- 只能使用chrome瀏覽器來測試,這是由於puppeteer本身的限制決定的
- 還無法支持sourcemap,2.0中會支持添加sourcemap來進行調試