Web调试技术详解

  • 苏格团队
  • 做者:Jonny

1、调试技术的起源

对于每位开发者而言,bug已是不能再寻常的东西,debug也是屡见不鲜的事情。然而寻根溯源起来,还得从上个世纪五十年代讲起。css

1947年9月9日,哈佛大学在测试马克II型艾肯中继器计算机的时候,一只飞蛾粘在一个继电器上,致使计算机没法正常工做,操做员把飞蛾移除以后,计算机又恢复了正常运转。因而他们将这只飞蛾贴在了他们当时记录的日志上,并在日志最后写了这样一句话:First actual case of bug being found。这是他们发现的第一个真正意义上的 bug,这也是人类计算机软件历史上发现的第一个 bug。他们也提出了一个词,“debug(调试)”了机器,由此引出了计算机调试技术的发展。前端

2、Chrome 开发者工具

对于web前端而言,咱们天天都在使用开发调试工具进行查看dom结构、js断点和查看分析登陆请求等操做,最熟悉的开发调试工具 应该莫过于Chrome的Devtools和Firefox的FireBug了。node

Chrome 开发者工具实际上是一个用 HTML,JavaScript 和 CSS 写的 Web 应用程序,被集成在浏览器中。其基于远程调试协议,与浏览器架构关系以下:git

由图可知:github

  • 远程调试协议基于 WebSocket,利用 WebSocket 创建链接 DevTools 和浏览器内核的快速数据通道
  • 浏览器拥有多个 Tab,并为每一个 Tab 单独提供 Websocket 的 Endpoint URI
  • 每一个 DevTool 实例只能检视一个 Tab,即只能与一个 Tab 保持通信

事实上,Chrome开发者工具不只只是能够在当前的浏览器页面直接打开,它做为一个客户端(开源),也能够用来调试任何支持远程调试协议的浏览器。web

使用文档:developers.google.com/web/tools/c…chrome

github仓库:github.com/ChromeDevTo…json

3、远程调试协议(remote debugging protocol)

远程调试协议Webkit 在 2012 年就已经引入,目前全部 Webkit 内核的浏览器都支持这一特性。远程调试协议基于 WebSocket,利用 WebSocket 创建链接 客户端(如DevTools) 和浏览器内核的快速数据通道,Chrome的Devtools仅仅只是Webkit远程调试协议的一个应用案例。浏览器

  1. 通信模式和消息结构: 对于每一个页面的全部操做,远程调试协议将其划分红了不一样的命令域,如Browser、Dom、Debugger和Network等等,每一个域定义了不一样的命令和事件。在开发调试过程当中,浏览器内核和远程客户端经过WebSocket发送消息进行通讯,消息基本上分两种格式,一种是含有 message id 的,另外一种是不含 message id 的,分别表明俩种通信模式:
  • request/response:就如同一个异步调用,经过请求的信息,获取相应的返回结果。这样的通信必然有一个 message id,不然两方都没法正确的判断请求和返回的匹配情况。

  • notification:和第一种不一样,这种模式用于由一方单方面的通知另外一方某个信息。和 “事件” 的概念相似。

  1. Chrome的上层封装: 为了更加方便Chrome extension的开发,Chrome调试器扩展API提供了更高级别的API ——Chrome Debugger API。此API隐藏请求ID并处理请求与其响应的绑定,所以容许sendCommand在回调函数调用中处理结果。每一个 command 包含 request 和 response 两部分,request 部分指定所要进行的操做以及操做说要的参数,response 部分代表操做状态,成功或失败。

以Debugger Domain为例,安全

  • command结构以下:

  • 事件结构以下:

协议文档:chromedevtools.github.io/devtools-pr…

Debugger API: developer.chrome.com/extensions/…

咱们能够经过devtools来查看Devtools Extension与浏览器内核实际通讯的数据状况,步骤以下:

一、开启开发者工具实验模式:

  • 浏览器进入chrome://flags
  • 找到Developer Tools Experiments
  • 状态改成enable
  • 重启浏览器

二、打开协议监控tab

  • 点击devtools工具右上角菜单图标,进入“settings”,左边选择“Experiments”tab,将“Protocol Monitor”打上勾
  • 关闭devtools后从新打开,点击devtools工具右上角菜单图标,再进入“More Tools”,选择“Protocol monitor"

以后咱们即可以看到:

4、Chrome的远程调试模式:

从上面咱们已经知道,Devtools是如何基于远程调试协议与浏览器内核进行交互的了,然而,不只仅如此,Chrome还能够开启远程调试模式,容许外部客户端(支持远程调试协议)对其进行调试。

  1. 协议Server端:

首先,以远程调试模式打开Chrome:

./chrome --remote-debugging-port=9222

以后调试数据会转发到本地9222端口,浏览器输入localhost:9222/json能够看到:

其中咱们能够看到每一个tab页面对应的websocket url,经过该url创建链接即可以和系统内核进行通讯了。

  1. 协议客户端:

咱们能够采用Chrome内置的工具与其创建链接进行调试,步骤以下:

1)打开Chrome 内置客户端,在浏览器输入:

http://localhost:9222

能够看到如下界面:

2)或者在chrome://inspect界面,咱们能够发现,此时本地浏览器也能够被做为一个remote device来调试了。

3)咱们也能够采用一个外部的调试工具,如node程序,vscode插件等,经过从9222端口获取到各个页面的json数据,而后进行websocket链接进行通讯,进行实现各类丰富的开发调试功能。

5、移动端远程调试技术:

从上面看,chrome等浏览器的远程调试模式彷佛有点鸡肋,我都有Devtools工具了,何须还要画蛇添足去开启远程调试模式用其余工具来调试。别急,远程调试模式真正发挥做用的仍是移动端设备的调试场景。移动端设备有运行环境,却没有合适的开发和调试环境,借助于webkit的远程调试模式,可使得咱们很方便的查看和调试移动端设备。

移动端web远程调试技术不少种,像weinre等在代码中嵌入脚本的就不说了,咱们以基于webkit远程调试协议的方式来说解。 从上面咱们已经知道,移动端chrome开启远程调试模式后json数据会被打到debugging端口(localhost:9222),由于安全考虑,chrome限制了只能是本地localhost的,不能打到指定ip之上。此时,须要经过某种方式,将移动端9222端口的数据绑定到pc端,以后才能PC端即可以经过PC端本地端口与移动端页面进行调试。

一、端口绑定方式:

  • 有线(USB线):以webkit为内核的移动端浏览器,开启浏览器远程调试功能以后经过usb链接到pc端,以后经过adb进行端口绑定:

adb forward tcp:9222 localabstract:chrome_devtools_remote

  • 无线(network):经过ssh 进行端口转发,本方式适合移动端支持ssh链接登陆。

#在本地主机A1登录远程云主机B1,并进行本地端口转发。2000端口绑定本地全部网卡 ssh -L 2000:localhost:3000 root@192.168.*.*

6、调试服务器脚本(node程序):

2016年,Node将 Chrome浏览器的"开发者工具"做为官方的调试工具,使得 Node 脚本也可使用图形界面调试,这大大方便了开发者。开启调试方式以下:

node --inspect --debug-brk index.js

而后经过chrome://inspect能够看到app.js的调试入口,打开以后出现Devtools的定制版,只有四个Tab,移除了和服务器脚本调试无关的部分。

能够发现,node脚本调试的原理与chrome js脚本类似,其内置V8支持远程调试协议,开启调试后做为一个server端,devtools客户端经过websocket与其创建链接进行通讯。

6、总结

至此,咱们已经介绍了本地调试和远程调试已经隐藏在其背后的通信原理。远程调试协议做为一个强大的通用的协议,支持了不一样server或客户端的通讯。

浏览器的调试,其实最后都落脚到引擎:渲染引擎和 JavaScipt 引擎。对于css的修改、js的断点等,如何落实到渲染引擎上,上下文环境切换,函数调用栈追踪等等,还有更多东西值得挖掘。

相关文章
相关标签/搜索