前端遠程調試
調試是開發過程很重要的過程,而隨著移動端的普及,移動開發也越來越多,並且由於移動端的諸多限制,使得調試相對PC複雜很多。因此遠程調試就顯得非常重要了。
近幾年,瀏覽器廠商也紛紛推出自己的遠程調試工具,比如Opera Mobile 推出的Opera Dragonfly,iOS Safari 可以開啟Web檢查器在 Mac OS X系統中實現遠程調試。Android 4.0+系統的 Chrome for Android可以配合 ADB(Android Debug Bridge)實現桌面遠程調試,桌面版Chrome 32+已經支持免安裝ADB即可實現遠程調試移動設備頁面/WebView 。國內的UC瀏覽器開發者版也推出了自己的遠程調試工具RemoteInspector。除了瀏覽器廠商之外,也湧現出許多第三方開發的遠程調試工具,諸如支持全平台調試的Weinre等。
本文主要介紹遠程調試是什麼,基本原理是什麼,有哪些情況,以及如何根據不同的情況選擇恰當優雅的調試方式。
本地調試
遠程調試是相對於本地調試來講的,那麼理解本地調試對於理解遠程調試是很重要的。
本地調試指的是直接調試運行在本地的APP。常見的就是調試本地PC(很簡單)。
比如我在本地運行了一個webpack-dev-server,埠號為8080.
那麼訪問8080,並且打開瀏覽器的開發者工具,就可以在本地進行調試了。再比如我要調試google的官網,那麼我只需要
遠程調試
那麼遠程調試就是調試運行在遠程的APP。比如手機上訪問google,我需要在PC上調試手機上運行的google APP。
這個就叫做遠程調試。
遠程調試大概有三種類型:
* 調試遠程PC(本質上是一個debug server 和 一個debug target,其實下面兩種也是這種模型,ios中間會多一個協議轉化而已)
這種類型下的debug target就是pc, debug server 也是pc。
* 調試android webpage/webview(很多方式,但安卓4.4以後本質都是Chrome DevTools Protocol的擴展)
這種類型下的debug target就是android webview,debug server 是pc。
* 調試ios webpag/webview(可以使用iOS WebKit Debug Proxy代理,然後問題便退化成上述兩種場景)
這種類型下的debug target就是ios webview, debug server 是pc。
chrome遠程調試
提到chrome的遠程調試,就不得不提[chrome remote debug protocol](https://developer.chrome.com/devtools/docs/debugger-protocol)。
它採用websocket來與頁面建立通信通道,由發送給頁面的command和data組成。chrome的開發者工具是這個協議主要的使用者,第三方開發者也可以調用這個協議來與頁面交互調試。簡而言之,有了它我們就可以和chrome中的頁面進行雙向通信。
chrome 啟動的時候,默認是關閉了調試埠的,如果要對一個chrome PC 瀏覽器進行調試,那麼啟動的時候,可以通過傳遞參數來開啟 Chrome 的調試開關:
```
sudo /Applications/Google Chrome.app/Contents/MacOS/Google Chrome --remote-debugging-port=9222
```
這個時候就可以通過http://127.0.0.1:9222 查看所有遠程調試目標
http://127.0.0.1:9222/json 可以查看特定的遠程調試目標信息,類型為json數組。
```json
[
{
"description": "",
"devtoolsFrontendUrl": "/devtools/inspector.html?ws=127.0.0.1:9222/devtools/page/fefa.....-ffa",
"id": "fefa.....-ffa",
"title": "test",
"type": "page",
"url": "http://127.0.0.1:51004/view/:id",
"webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/page/fefa.....-ffa"
}
]
```
其中id是一個唯一的標示,[chrome dev protocol](https://chromedevtools.github.io/devtools-protocol/)基本都依賴這個id。
比如關閉一個頁面:
```json
http://localhost:9222/json/close/477810FF-323E-44C5-997C-89B7FAC7B158
```
再比如激活一個頁面:
```json
http://localhost:9222/json/activate/477810FF-323E-44C5-997C-89B7FAC7B158
```
具體可以查看官方信息。
webSocketDebuggerUrl是調試頁面需要用到的WebSocket連接的地址。
比如我需要清空瀏覽器緩存,就用websocket連接到該頁面之後調用send方法
```js
const ws = new WebSocket("ws://127.0.0.1:9222/devtools/page/fefa.....-ffa")
ws.send("{"id": 1, "method": "Network.clearBrowserCache", "params": {}}")
```
還有很多類似的api,因此就可以構造複雜的[擴展](https://developer.chrome.com/extensions/samples)
常見的遠程調試框架對比
明白了遠程調試的類型,那麼對於不同的類型應該採取什麼樣的手段是我們最為關心的問題。
在回答這個問題之前,我們先來看下市面上的遠程調試框架,他們做了什麼事情,解決了什麼問題。
如下是我對比較常見的遠程調試框架的簡單對比。
後面虛線裡面的是除了抓包功能之外調試框架,可以看出灰色部分是他們不支持的。
這時候就需要專門的抓包工具來代替。通常來說專門的抓包工具功能包括但不限於請求攔截和修改,https支持,重放和構造請求,(web)socket。
抓包工具的原理非常簡單,本質上它就是一個正向代理,所有的請求經過它,就可以將其記錄下來,甚至可以重放構造請求等。
對於抓包工具,步驟基本就是三部曲。
第一步:手機和PC保持在同一網路下(比如同時連到一個Wi-Fi下)
第二步:設置手機的HTTP代理,代理IP地址設置為PC的IP地址,埠為代理的啟動埠。
Android設置代理步驟:設置 - WLAN - 長按選中網路 - 修改網路 - 高級 - 代理設置 - 手動
iOS設置代理步驟:設置 - 無線區域網 - 選中網路 - HTTP代理手動
對於https請求需要多一步:
第三步:手機安裝證書。
> 對於第二步,我們可以通過連接USB的方式,然後設置埠轉發和虛擬主機映射,建立tcp連接,這樣就ip就可以設置為localhost,以後ip變動,代理設置也不必變動,但是卻需要連接USB,可謂各有千秋。
## 調試的輔助手段
通過上面的方式我們已經建立了調試的準備環境。但是真正調試應用,發現問題,解決問題。還需要
其他信息來輔助。下面來講解一些調試的輔助手段。
用戶軌跡
有時候我們需要知道用戶的瀏覽軌跡,從而方便定位問題。
瀏覽軌跡的粒度可以自己決定,可以是組件級,也可以是頁面級。
應用數據
獲取足夠的信息對於調試是非常重要的。尤其是數據驅動(data driven)的應用,
知道了數據,基本上就可以還原現場,定位問題。
比如我們使用vuex或者redux這樣的狀態管理框架,一種方式是將中央的store掛載到window上。
這樣我們就可以通過訪問window的屬性獲取到全局的store。
如果使用其他的狀態管理框架或者自製的狀態管理,也可以採取類似的方式。
然而我們也可以使用現成的工具,比如使用react-dev-tools調試react應用。
比如使用redux-dev-tools調試使用redux的應用等等。
其他調試信息
比如用戶的id,客戶端數據,登陸的session信息等等對於調試有所幫助的,都可以將其收集起來。
參考
https://www.jianshu.com/p/19c18c924f91
https://aotu.io/notes/2017/02/24/Mobile-debug/index.html
TAG:Mr丶L |