用whistle實現map local

avenwu發表於2018-05-01

web本地開發除錯過程中,經常需要用本地檔案替換請求或者將請求轉發到本地的指定伺服器,即map local功能,而實際中用到的map local功能往往會遇到各種更加複雜的情形,比如請求url裡面包含md5,替換combo請求,替換jsonp請求,有時還需要對不同頁面發出的請求替換不同檔案或目錄等等,本文將講下如何用whistle來實現各種map local功能。

whistle是基於Node實現的跨平臺抓包除錯代理工具,功能上不僅涉及抓包除錯代理工具的方方面面,且整合了weinre及自定義的log功能用於除錯移動端頁面,所有操作只需通過類似hosts的簡單配置方式實現,並支援通過外掛擴充套件功能,具體功能及安裝使用請直接訪問Github:github.com/avwo/whistl…

whistle的每種操作對應一個協議,其中map local功能主要涉及 filetplxfilextpl 四種協議及外掛擴充套件:

規則配置示例圖

檔案替換

如果用域名、路徑或通配路徑的方式匹配,whistle會根據匹配url的剩餘路徑自動補齊本地檔案路徑,並自動忽略後面的請求引數:

# 域名匹配
www.test.com E:\workspace\test # 等價於 file://E:\workspace\test 或 file://E:/workspace/test
# Mac或Linux
www.test.com /usr/workspace/test # 等價於 file:///usr/workspace/test

# 路徑匹配
www.test.com/abc E:\workspace\test # 等價於 file://E:\workspace\test
# Mac或Linux
www.test.com/abc /usr/workspace/test # 等價於 file:///usr/workspace/test

# 萬用字元路徑匹配
*/ E:\workspace\test # 等價於 file://E:\workspace\test
# Mac或Linux
*/abc /usr/workspace/test # 等價於 file:///usr/workspace/test
複製程式碼

域名匹配和萬用字元路徑匹配都可以看成路徑匹配,區別是:

  1. 域名匹配可以匹配帶任意埠的改域名url,即 www.test.com file://E:\workspace\test 可以同時匹配 https://www.test.com:8080/xxxhttp://www.test.com/xxx 等請求
  2. 萬用字元匹配和域名匹配的區別是萬用字元路徑可以匹配任何域名的對應路徑

路徑匹配會匹配該路徑及其子路徑的url,並把超出的路徑自動補齊到本地指定的檔案路徑,如配置規則 www.test.com/abc E:\workspace\test 後,請求 http://www.test.com/abchttps://www.test.com/abc/index.html(允許帶請求引數http://www.test.com/abc?xxxhttps://www.test.com/abc/index.html?xxx)分別對映到本地檔案 E:\workspace\testE:\workspace\test\index.html,如果對應檔案不存在,則返回404。

如果你不想自動補齊,可以配置:

www.test.com <E:\workspace\test> # 等價於 file://<E:\workspace\test>
複製程式碼

上述配置所有www.test.com域名下的請求都只會被 E:\workspace\test 替換

如果你想指定某個固定的url匹配指定檔案,不希望其子路徑也匹配規則,可以用精確匹配:

$www.test.com E:\workspace\test\index.html
複製程式碼

上述配置只有 http://www.test.com/https://www.test.com/?xxx 類似根路徑url才會匹配,http://www.test.com/abc 則不會匹配規則。

自動忽略url裡面的md5串

去掉url裡面的md5,可以用兩種方式,一種是直接用正則匹配,另一種是跟下面根據referer替換的方式一樣,用reqScrip實現具體用法參考下面的根據referer替換,這邊以正則為例:

# www.test.com/abc E:\workspace\test 
/^[^/]+://www\.test\.com/abc/([^?]+)\.[\da-f]+(\.\w+)/i E:\workspace\test/$1$2
# 這裡 /$1$2 不能改成 \$1$2,因為 \ 是個轉義字元

# 也可用萬用字元正則匹配
^www.test.com/abc/**.*.*  E:\workspace\test/$1.$3
複製程式碼

正則匹配或萬用字元正則匹配沒有自動補齊功能,但可以通過正則子匹配實現自動補齊路徑的功能,其中,$&$0 表示整個請求url,$1, $2, ..., $9 分別表示正則裡面的第1到第10個子匹配,如果你的路徑包含 $&\ 為轉義字元,\$x 可以讓whistle不要進行子匹配替換 。

上述配置類似請求 http://www.test.com/abc/dev/index.ec6abf23.js 會對映到本地檔案 E\workspace\test\dev\index.js,有關正則和萬用字元正則匹配的內容可以參見:匹配模式

替換jsonp請求

由於jsonp請求需要把url裡面的callback寫入到響應內容裡面,這裡需要用到whistle的tpl協議,tpl支援用請求引數值替換檔案裡面對應的 {xxx} 佔位符:

www.test.com/cgi-jsonp tpl://E:\test
複製程式碼

如果 E:\test\ 裡面有檔案 data.json

{callback}({"ec": 0})
複製程式碼

請求 www.test.com/cgi-jsonp/data.json?callback=testCallback,返回:

testCallback({"ec": 0})
複製程式碼

列表替換

有時靜態檔案分佈的本地的各個目錄,但又分不清檔案具體在哪個目錄,這時就可以用檔案列表替換功能:

www.test.com/abc E:\workspace\test|E:\workspace\test2|E:\workspace\test3
# jsonp請求替換
www.test.com/cgi-jsonp E:\test|E:\test2|E:\test3
複製程式碼

上述配置匹配規則的請求會依次在各個目錄尋找對應檔案,如果找不到則返回404。

xfile、xtpl替換

上面file和tpl協議請求找不到對應的匹配檔案,會直接返回404,如果想要找不到本地匹配檔案時直接請求線上,可以用xfile和xtpl:

www.test.com/abc xfile://E:\workspace\test|E:\workspace\test2|E:\workspace\test3
# jsonp請求替換
www.test.com/cgi-jsonp xtpl://E:\test|E:\test2|E:\test3
複製程式碼

根據referer替換

在同時開發測試多個頁面,且這些頁面裡面的js、css、圖片等靜態資源要對映的不同的目錄,又不清楚這些頁面靜態資源的url結構,這時需要通過請求referer來動態判斷規則,可以用whistle的reqScrip實現:

在whistle介面Values中建立一個checkReferer.js

const referer = headers.referer || '';
if (headers.referer.indexOf('download.html') !== -1) {
	rules.push('*/ E:/test/download');
} else {
	rules.push('*/ E:/test/dev');
}
複製程式碼

在Rules配置規則:

*.cdn.cn reqScript://{checkReferer.js}
複製程式碼

reqScript示例圖
*.cdn.cn 的請求會根據它所在頁面設定不同的規則。

請求轉發

現在用webpack做構建時,習慣引入webpack-dev-server做記憶體靜態伺服器,可以用whistle把對應請求轉發到該靜態伺服器,假設個靜態伺服器的埠為6666

*.cdn.cn/test http://127.0.0.1:6666
複製程式碼

這時請求 https://x.cdn.cn/test/xxx 會被請求 http://127.0.0.1:6666/xxx 替換。

替換combo請求

理論上whistle可以處理所有map local的功能,如果需要一些更復雜的功能,如替換combo請求,可以用外掛whistle.combo實現,也可以通過自定義whistle外掛簡化自身業務的配置。

map loca只是whistle其中一個功能,有關whistle的更多功能請訪問Gihtub:github.com/avwo/whistl…

相關文章