前端远程调试

原文刊登在个人githubhtml

调试是开发过程很重要的过程,而随着移动端的普及,移动开发也愈来愈多,而且因为移动端的诸多限制,使得调试相对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等。vue

本文主要介绍远程调试是什么,基本原理是什么,有哪些状况,以及如何根据不一样的状况选择恰当优雅的调试方式。react

本地调试

远程调试是相对于本地调试来说的,那么理解本地调试对于理解远程调试是很重要的。 本地调试指的是直接调试运行在本地的APP。常见的就是调试本地PC(很简单)。 好比我在本地运行了一个webpack-dev-server,端口号为8080. 那么访问8080,而且打开浏览器的开发者工具,就能够在本地进行调试了。再好比我要调试google的官网,那么我只须要 访问www.google.com, 一样打开开发者工具就能够进行本地调试了。android

远程调试

那么远程调试就是调试运行在远程的APP。好比手机上访问google,我须要在PC上调试手机上运行的google APP。 这个就叫作远程调试。webpack

远程调试大概有三种类型:ios

  • 调试远程PC(本质上是一个debug server 和 一个debug target,其实下面两种也是这种模型,ios中间会多一个协议转化而已) 这种类型下的debug target就是pc, debug server 也是pc。git

  • 调试android webpage/webview(不少方式,但安卓4.4之后本质都是Chrome DevTools Protocol的扩展) 这种类型下的debug target就是android webview,debug server 是pc。github

  • 调试ios webpag/webview(可使用iOS WebKit Debug Proxy代理,而后问题便退化成上述两种场景) 这种类型下的debug target就是ios webview, debug server 是pc。web

chrome远程调试

提到chrome的远程调试,就不得不提chrome remote debug protocol。 它采用websocket来与页面创建通讯通道,由发送给页面的command和data组成。chrome的开发者工具是这个协议主要的使用者,第三方开发者也能够调用这个协议来与页面交互调试。简而言之,有了它咱们就能够和chrome中的页面进行双向通讯。vuex

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数组。

[
  {
    "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基本都依赖这个id。

好比关闭一个页面:

http://localhost:9222/json/close/477810FF-323E-44C5-997C-89B7FAC7B158
复制代码

再好比激活一个页面:

http://localhost:9222/json/activate/477810FF-323E-44C5-997C-89B7FAC7B158
复制代码

具体能够查看官方信息。

webSocketDebuggerUrl是调试页面须要用到的WebSocket链接的地址。

好比我须要清空浏览器缓存,就用websocket链接到该页面以后调用send方法

const ws = new WebSocket('ws://127.0.0.1:9222/devtools/page/fefa.....-ffa')
ws.send('{"id": 1, "method": "Network.clearBrowserCache", "params": {}}')
复制代码

还有不少相似的api,所以就能够构造复杂的扩展

常见的远程调试框架对比

明白了远程调试的类型,那么对于不一样的类型应该采起什么样的手段是咱们最为关心的问题。 在回答这个问题以前,咱们先来看下市面上的远程调试框架,他们作了什么事情,解决了什么问题。

以下是我对比较常见的远程调试框架的简单对比。

remote-debug

后面虚线里面的是除了抓包功能以外调试框架,能够看出灰色部分是他们不支持的。 这时候就须要专门的抓包工具来代替。一般来讲专门的抓包工具功能包括但不限于请求拦截和修改,https支持,重放和构造请求,(web)socket。

抓包工具的原理很是简单,本质上它就是一个正向代理,全部的请求通过它,就能够将其记录下来,甚至能够重放构造请求等。

对于抓包工具,步骤基本就是三部曲。

第一步:手机和PC保持在同一网络下(好比同时连到一个Wi-Fi下)

第二步:设置手机的HTTP代理,代理IP地址设置为PC的IP地址,端口为代理的启动端口。

Android设置代理步骤:设置 - WLAN - 长按选中网络 - 修改网络 - 高级 - 代理设置 - 手动 iOS设置代理步骤:设置 - 无线局域网 - 选中网络 - HTTP代理手动

对于https请求须要多一步:

第三步:手机安装证书。

对于第二步,咱们能够经过链接USB的方式,而后设置端口转发和虚拟主机映射,创建tcp链接,这样就ip就能够设置为localhost,之后ip变更,代理设置也没必要变更,可是却须要链接USB,可谓各有千秋。

远程调试服务

经过使用上面提到的框架(或者是本身写的拥有上面基本功能的框架), 咱们已经能够很方便地进行调试了。 可是事实上大多数公司都是开发者在本地进行调试。这就形成了不少问题,好比

  • 若是手机在不一样的开发者电脑调试,就须要在一个手机安装多个证书。
  • 开发者须要本身配置代理配置文件,共享须要手动导出导入相对麻烦。
  • 若是开发者本地的ip发生变更,那么就须要修改手机的代理ip(不使用usb走虚拟主机映射的状况) ......

针对以上等问题,若是搭建一个远程的调试服务(产品),那么问题就能够很好的解决。

理想的情况是,手机仅仅须要配置一次(安装证书,设置代理等),之后调试的时候就能够直接查看该手机的请求以及控制台,元素等等,而且直接指定映射到任何电脑 进行pc端调试。不一样开发者之间能够方便的共享配置(好比有一个集团或公司的共有配置)。

拿搭建一个whistle的服务为例。

下载项目并启动:

npm install whistle -g --registry=https://registry.npm.taobao.org

w2 start
复制代码

设置代理:

好比设置手机的代理为x.x.x.x:8899

> x.x.x.x 为部署服务的ip地址,8899为默认端口,若修改了,则对应修改成修改后的端口号

dashboard

访问http://x.x.x.x:8899/,会看到以下的页面:    

whistle dashboard
   咱们能够在network查看远程的网络请求,能够经过其内置的weinre查看元素,控制台等    能够看到咱们配置了三套配置,分别为默认配置,项目一和项目二。

简单介绍下配置作了什么。    前两个就是简单地将请求映射到本地。    第三条配置会拦截www.duiba.com.cn 的请求,并在html中注入一端weinre脚本。拦截成功就能够经过访问http://x.x.x.x:8899/weinre/client/#sword 访问对应的开发者工具进行调试。  

weinre-client
  其余功能:

Network:主要用来查看请求信息,构造请求,页面 console 打印的日志及抛出的js错误等

Rules:配置操做规则

Plugins:安装的插件信息,及启用或禁用插件

Weinre:设置的weinre列表

HTTPS:设置是否拦截HTTPS请求,及下载whistle根证书

咱们能够进一步安装证书支持https拦截,配置帐号系统,日志映射等等, 部署一个其余的远程调试框架的基本思想和步骤基本是同样的。

通过上面的步骤咱们已经获得了一个集中式的调试服务器,咱们不须要在本地配置复杂的环境和配置了, 而且足够灵活,咱们能够查看全部请求,随意更改请求,而且直接代理到本地尽心调试。

实际状况咱们还会遇到不少其余问题,经过扩展框架的功能丰富功能是很是有必要的,这个时候框架的扩展性就很重要了。

调试的辅助手段

经过上面的方式咱们已经创建了调试的准备环境。可是真正调试应用,发现问题,解决问题。还须要 其余信息来辅助。下面来说解一些调试的辅助手段。

用户轨迹

有时候咱们须要知道用户的浏览轨迹,从而方便定位问题。 浏览轨迹的粒度能够本身决定,能够是组件级,也能够是页面级。

应用数据

获取足够的信息对于调试是很是重要的。尤为是数据驱动(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

欢迎关注个人公众号,不定时更新。

公众号
相关文章
相关标签/搜索