简介
chrome-remote-interface是chrome调试协议的第三方调试客户端实现,该项目开源,提供了命令行工具,且为node程序提供了api。
chrome-remote-interface为基于chrome调试协议编写自己的node调试工具提供了便捷的途径,因为利用它,你不需要基于原始的协议通过websocket编程去开发调试工具了。
项目地址https://github.com/cyrus-and/chrome-remote-interface。
使用命令行
安装
通过npm进行安装
npm install chrome-remote-interface
启动调试目标
chrome-remote-interface基于chrome调试协议,因此其支持调试chrome浏览器和node运行环境。
无论哪种调试目标,其启动时都应该指定调试端口。
如果要调试chrome浏览器,应该在启动chrome时添加--remote-debugging-port参数,如下:
goole-chrome --remote-debugging-port=9222
如果调试node,在启动时添加--inspect参数,如下:
node --inspect=9222 app.js
此时,node会输出:
Debugger listening on port 9222.
Warning: This is an experimental feature and could change at any time.
To start debugging, open the following URL in Chrome:
chrome-devtools://devtools/remote/serve_file/@60cd6e859b9f557d2312f5bf532f6aec5f284980/inspector.html?experiments=true&v8only=true&ws=localhost:9222/2894362d-f2d1-4f3b-a9e8-4e27da5714ef
题外话:如果只是希望调试node,并不打算开发一个调试node的工具的话,根据提示中的url,在chrome中打开就直接可以用chrome的开发工具调试了。
体验命令行
-
查看全部命令
在终端输入chrome-remote-interface并回车,可看到如下输出:
Usage: chrome-remote-interface [options] [command]
Commands:
inspect [options] [] inspect a target (defaults to the current tab)
list list all the available tabs
new [] create a new tab
activate activate a tab by id
close close a tab by id
version show the browser version
protocol [options] show the currently available protocol descriptor
Options:
-h, --help output usage information
-t, --host HTTP frontend host
-p, --port HTTP frontend port
```
其中,new和close是针对浏览器的tab的命令,不要针对node来运行。
-
查看所有页面实例
chrome-remote-interface -t 127.0.0.1 -p 9222 list
输出如下:
[ { description: 'node.js instance', devtoolsFrontendUrl: 'https://chrome-devtools-frontend.appspot.com/serve_file/@60cd6e859b9f557d2312f5bf532f6aec5f284980/inspector.html?experiments=true&v8only=true&ws=localhost:9222/2894362d-f2d1-4f3b-a9e8-4e27da5714ef', faviconUrl: 'https://nodejs.org/static/favicon.ico', id: '2894362d-f2d1-4f3b-a9e8-4e27da5714ef', title: 'app.js', type: 'node', url: 'file:///Users/renbaogang/git/enzyme.node/app.js', webSocketDebuggerUrl: 'ws://localhost:9222/2894362d-f2d1-4f3b-a9e8-4e27da5714ef' } ]
其中devtoolsFrontendUrl可以在chrome地址栏中回车该url,打开chrome的开发工具,可以直接用该工具调试。和启动node时,node提示的url是一个用途。
id是当前页面标识。
url是当前页面url。
webSocketDebuggerUrl是node提供的ws协议的调试服务,调试客户端需要通过该url连接到调试服务。 -
查看调试目标版本
chrome-remote-interface -t 127.0.0.1 -p 9222 version
输出:
[ { Browser: 'node.js/v7.0.0', 'Protocol-Version': '1.1' } ]
-
查看调试目标支持的调试协议
chrome-remote-interface -t 127.0.0.1 -p 9222 protocol
输出:
{ remote: false, descriptor: { { version: { major: '1', minor: '2' }, domains:[略] } }
remote:false说明协议内容是工具自带的协议文件,并不是来自调试目标。
如果要获取调试目标的协议内容要添加-r选项,如:chrome-remote-interface -t 127.0.0.1 -p 9222 protocol -r
输出:
{ remote: true, descriptor: { { version: { major: '1', minor: '1' }, domains:[略] } }
-
调试命令
chrome-remote-interface -t 127.0.0.1 -p 9222 inspect -r
-r 表示应用调试目标提供的协议描述文件
通过inspect可以调试node或chrome所支持的各个域。Console域体验
Console.enable()
{ result: {} }
Console.clearMessages()
{ result: {} }
```
Debugger域体验
```
Debugger.enable()
{ result: {} }
Debugger.setBreakpointsActive({active:true})
{ result: {} }
```
HeapProfiler域体验
```
HeapProfiler.enable()
{ result: {} }
HeapProfiler.startTrackingHeapObjects({trackAllocations:true})
{ result: {} }
```
Profiler域体验
```
Profiler.enable()
{ result: {} }
Profiler.start()
{ result: {} }
Profiler.stop()
{ result:
{ profile:
{ nodes:
[ { id: 1,
callFrame:
{ functionName: '(root)',
scriptId: '0',
url: '',
lineNumber: -1,
columnNumber: -1 },
hitCount: 0,
children: [ 2 ] },
...
]
}
}
}
```
Runtime域体验
>>> Runtime.evaluate({expression:"1+1"})
{ result: { result: { type: 'number', value: 2, description: '2' } } }
Schema域体验
>>> Schema.getDomains()
{ result:
{ domains:
[ { name: 'Runtime', version: '1.1' },
{ name: 'Debugger', version: '1.1' },
{ name: 'Profiler', version: '1.1' },
{ name: 'HeapProfiler', version: '1.1' },
{ name: 'Schema', version: '1.1' } ] } }
```
体验事件处理
scriptParsed是Debugger域提供的脚本解析事件
```
>>> Debugger.scriptParsed(params=>params.url)
{ 'Debugger.scriptParsed': 'params=>params.url' }
{ 'Debugger.scriptParsed': '' }
{ 'Debugger.scriptParsed': '/Users/renbaogang/git/enzyme.node/node_modules/negotiator/lib/encoding.js' }
```
## API ##
1. module([options], [callback])
基于chrome调试协议连接调试目标
options object类型,具有如下属性:
- host 默认localhost
- port 默认9222
- chooseTab 决定调试哪个tab。该参数可以为三种类型:
- function 提供一个返回tab序号的函数
- object 正如new 和 list返回的对象一样
- string websocket url
默认为一个函数,返回当前激活状态的tab的序号,如:function(tabs){return 0;}
- protocol 协议描述符,默认由remote选项来定是否使用调试目标提供的协议描述符
- remote 默认false,如果protocol设置了,该选项不会起作用
callback
如果callback是函数类型,则该函数在connect事件发生后会得到回调,并返回EventEmitter对象,如果不是,则返回Promise对象。
EventEmitter对象支持如下事件:
- connect
```
function (chrome) {}
```
当websocket连接建立后触发,chrome是Chome类型的实例。
- disconnect
```
function () {}
```
关闭websocket连接时触发
- error
```
function (err) {}
```
当通过host:port/json无法到达,或websocket连接无法建立时触发
err,Error类型的错误对象
使用样例,针对chrome浏览器:
```
const Chrome = require('chrome-remote-interface');
Chrome(function (chrome) {
with (chrome) {
Network.requestWillBeSent(function (params) {
console.log(params.request.url);
});
Page.loadEventFired(function () {
close();
});
Network.enable();
Page.enable();
once('ready', function () {
Page.navigate({'url': 'https://github.com'});
});
}
}).on('error', function (err) {
console.error('Cannot connect to Chrome:', err);
});
```
2. module.Protocol([options],[callback])
获取chrome调试协议描述符
options object类型,具有如下属性:
- host 默认localhost
- port 默认9222
- remote 默认false
callback 回调函数,在获取到协议内容后调用,函数接收如下参数:
- err Error一个错误对象,如果有错误的话
- protocol 包含以下属性
- remote 是否远程协议
- descriptor chrome调试协议描述符
使用样例:
```
const Chrome = require('chrome-remote-interface');
Chrome.Protocol(function (err, protocol) {
if (!err) {
console.log(JSON.stringify(protocol.descriptor, null, 4));
}
});
```
3. module.List([options], [callback])
获取所有的tabs,当然在node中只会有一个
options object类型,具有如下属性:
- host 默认localhost
- port 默认9222
- remote 默认false
callback 回调函数,在获取到tabs内容后调用,函数接收如下参数:
- err Error一个错误对象,如果有错误的话
- tabs 获取到的tab数组
使用样例:
```
const Chrome = require('chrome-remote-interface');
Chrome.List(function (err, tabs) {
if (!err) {
console.log(tabs);
}
});
```
4. module.New([options], [callback])
创建新的tab
options object类型,具有如下属性:
- host 默认localhost
- port 默认9222
- url 新tab加载的url 默认about:blank
callback 回调函数,在新tab创建后调用,函数接收如下参数:
- err Error一个错误对象,如果有错误的话
- tab 新增的tab
使用样例:
```
const Chrome = require('chrome-remote-interface');
Chrome.New(function (err, tab) {
if (!err) {
console.log(tab);
}
});
-
module.Activate([options], [callback])
激活指定tab
options object类型,具有如下属性:
- host 默认localhost
- port 默认9222
- id 目标tab的id
callback 回调函数,在新tab创建后调用,函数接收如下参数:
- err Error一个错误对象,如果有错误的话
使用样例:
```
const Chrome = require('chrome-remote-interface');
Chrome.Activate({'id': 'CC46FBFA-3BDA-493B-B2E4-2BE6EB0D97EC'}, function (err) {
if (!err) {
console.log('success! tab is closing');
}
});
```
-
module.Close([options], [callback])
关闭指定tab
options object类型,具有如下属性:
- host 默认localhost
- port 默认9222
- id 目标tab的id
callback 回调函数,在新tab创建后调用,函数接收如下参数:
- err Error一个错误对象,如果有错误的话
使用样例:
```
const Chrome = require('chrome-remote-interface');
Chrome.Close({'id': 'CC46FBFA-3BDA-493B-B2E4-2BE6EB0D97EC'}, function (err) {
if (!err) {
console.log('success! tab is closing');
}
});
```
-
module.Version([options], [callback])
获取版本信息
options object类型,具有如下属性:
- host 默认localhost
- port 默认9222
callback 回调函数,在新tab创建后调用,函数接收如下参数:
- err Error一个错误对象,如果有错误的话
- info json object
使用样例:
```
const Chrome = require('chrome-remote-interface');
Chrome.Version(function (err, info) {
if (!err) {
console.log(info);
}
});
```
-
Chrome 类
支持的事件:
-
event
在远程调试目标发送通知时触发,一般是远程对象执行了客户端提交的方法后
function (message) {}
message包含如下属性:
- method 通知内容,方法名 如:'Network.requestWillBeSent'
- params 参数内容
使用样例:
``` chrome.on('event', function (message) { if (message.method === 'Network.requestWillBeSent') { console.log(message.params); } }); ```
-
调试目标通过websocket发送了一个指定方法名的通知
function (params) {}
使用样例:
chrome.on('Network.requestWillBeSent', console.log);
-
ready
每次没有调试命令等待调试目标返回时触发
function () {}
使用样例:
只在Network和Page激活后加载一个url
chrome.Network.enable(); chrome.Page.enable(); chrome.once('ready', function () { chrome.Page.navigate({'url': 'https://github.com'}); });
-
支持的方法
- chrome.send(method, [params], [callback])
发送一个调试命令
method 命令名称
params 参数
callback 当远程对象对该命令发送一个应答后调用,函数具有以下参数:
- error boolean 是否成功
- response 如果error===true,返回一个error对象,{error:...},否则返回一个应答,{result:...}
注意:在chrome调试规范里提到的id字段,在这里被内部管理不会暴露给用户
使用样例:
```
chrome.send('Page.navigate', {'url': 'https://github.com'}, console.log);
```
- chrome..([params], [callback])
是chrome.send('.', params, callback);的一种变形
例如:
```
chrome.Page.navigate({'url': 'https://github.com'}, console.log);
```
- chrome..(callback)
是chrome.on('.', callback)的变形
例如:
```
chrome.Network.requestWillBeSent(console.log);
```
- chrome.close([callback])
关闭与远程调试目标的连接
callback会在websocket关闭成功后调用