• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

cyrus-and/chrome-remote-interface: Chrome Debugging Protocol interface for Node. ...

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

cyrus-and/chrome-remote-interface

开源软件地址:

https://github.com/cyrus-and/chrome-remote-interface

开源编程语言:

JavaScript 98.3%

开源软件介绍:

chrome-remote-interface Build Status

Chrome Debugging Protocol interface that helps to instrument Chrome (or any other suitable implementation) by providing a simple abstraction of commands and notifications using a straightforward JavaScript API.

This module is one of the many third-party protocol clients.

Sample API usage

The following snippet loads https://github.com and dumps every request made:

const CDP = require('chrome-remote-interface');

async function example() {
    let client;
    try {
        // connect to endpoint
        client = await CDP();
        // extract domains
        const {Network, Page} = client;
        // setup handlers
        Network.requestWillBeSent((params) => {
            console.log(params.request.url);
        });
        // enable events then start!
        await Network.enable();
        await Page.enable();
        await Page.navigate({url: 'https://github.com'});
        await Page.loadEventFired();
    } catch (err) {
        console.error(err);
    } finally {
        if (client) {
            await client.close();
        }
    }
}

example();

Find more examples in the wiki. You may also want to take a look at the FAQ.

Installation

npm install chrome-remote-interface

Install globally (-g) to just use the bundled client.

Implementations

This module should work with every application implementing the Chrome Debugging Protocol. In particular, it has been tested against the following implementations:

Implementation Protocol version Protocol List New Activate Close Version
Chrome tip-of-tree yes¹ yes yes yes yes yes
Opera tip-of-tree yes yes yes yes yes yes
Node.js (v6.3.0+) node yes no no no no yes
Safari (iOS) partial no yes no no no no
Edge partial yes yes no no no yes
Firefox (Nightly) partial yes yes no yes yes yes

¹ Not available on Chrome for Android, hence a local version of the protocol must be used.

The meaning of target varies according to the implementation, for example, each Chrome tab represents a target whereas for Node.js a target is the currently inspected script.

Setup

An instance of either Chrome itself or another implementation needs to be running on a known port in order to use this module (defaults to localhost:9222).

Chrome/Chromium

Desktop

Start Chrome with the --remote-debugging-port option, for example:

google-chrome --remote-debugging-port=9222
Headless

Since version 59, additionally use the --headless option, for example:

google-chrome --headless --remote-debugging-port=9222

Android

Plug the device and enable the port forwarding, for example:

adb forward tcp:9222 localabstract:chrome_devtools_remote

Note that in Android, Chrome does not have its own protocol available, a local version must be used. See here for more information.

WebView

In order to be inspectable, a WebView must be configured for debugging and the corresponding process ID must be known. There are several ways to obtain it, for example:

adb shell grep -a webview_devtools_remote /proc/net/unix

Finally, port forwarding can be enabled as follows:

adb forward tcp:9222 localabstract:webview_devtools_remote_<pid>

Opera

Start Opera with the --remote-debugging-port option, for example:

opera --remote-debugging-port=9222

Node.js

Start Node.js with the --inspect option, for example:

node --inspect=9222 script.js

Safari (iOS)

Install and run the iOS WebKit Debug Proxy. Then use it with the local option set to true to use the local version of the protocol or pass a custom descriptor upon connection (protocol option).

Edge

Start Edge with the --devtools-server-port option, for example:

MicrosoftEdge.exe --devtools-server-port 9222 about:blank

Please find more information here.

Firefox (Nightly)

Start Firefox with the --remote-debugging-port option, for example:

firefox --remote-debugging-port 9222

Bear in mind that this is an experimental feature of Firefox.

Bundled client

This module comes with a bundled client application that can be used to interactively control a remote instance.

Target management

The bundled client exposes subcommands to interact with the HTTP frontend (e.g., List, New, etc.), run with --help to display the list of available options.

Here are some examples:

$ chrome-remote-interface new 'http://example.com'
{
    "description": "",
    "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/b049bb56-de7d-424c-a331-6ae44cf7ae01",
    "id": "b049bb56-de7d-424c-a331-6ae44cf7ae01",
    "thumbnailUrl": "/thumb/b049bb56-de7d-424c-a331-6ae44cf7ae01",
    "title": "",
    "type": "page",
    "url": "http://example.com/",
    "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/b049bb56-de7d-424c-a331-6ae44cf7ae01"
}
$ chrome-remote-interface close 'b049bb56-de7d-424c-a331-6ae44cf7ae01'

Inspection

Using the inspect subcommand it is possible to perform command execution and event binding in a REPL fashion that provides completion.

Here is a sample session:

$ chrome-remote-interface inspect
>>> Runtime.evaluate({expression: 'window.location.toString()'})
{ result: { type: 'string', value: 'about:blank' } }
>>> Page.enable()
{}
>>> Page.loadEventFired(console.log)
[Function]
>>> Page.navigate({url: 'https://github.com'})
{ frameId: 'E1657E22F06E6E0BE13DFA8130C20298',
  loaderId: '439236ADE39978F98C20E8939A32D3A5' }
>>> { timestamp: 7454.721299 } // from Page.loadEventFired
>>> Runtime.evaluate({expression: 'window.location.toString()'})
{ result: { type: 'string', value: 'https://github.com/' } }

Additionally there are some custom commands available:

>>> .help
[...]
.reset    Remove all the registered event handlers
.target   Display the current target

Embedded documentation

In both the REPL and the regular API every object of the protocol is decorated with the meta information found within the descriptor. In addition The category field is added, which determines if the member is a command, an event or a type.

For example to learn how to call Page.navigate:

>>> Page.navigate
{ [Function]
  category: 'command',
  parameters: { url: { type: 'string', description: 'URL to navigate the page to.' } },
  returns:
   [ { name: 'frameId',
       '$ref': 'FrameId',
       hidden: true,
       description: 'Frame id that will be navigated.' } ],
  description: 'Navigates current page to the given URL.',
  handlers: [ 'browser', 'renderer' ] }

To learn about the parameters returned by the Network.requestWillBeSent event:

>>> Network.requestWillBeSent
{ [Function]
  category: 'event',
  description: 'Fired when page is about to send HTTP request.',
  parameters:
   { requestId: { '$ref': 'RequestId', description: 'Request identifier.' },
     frameId:
      { '$ref': 'Page.FrameId',
        description: 'Frame identifier.',
        hidden: true },
     loaderId: { '$ref': 'LoaderId', description: 'Loader identifier.' },
     documentURL:
      { type: 'string',
        description: 'URL of the document this request is loaded for.' },
     request: { '$ref': 'Request', description: 'Request data.' },
     timestamp: { '$ref': 'Timestamp', description: 'Timestamp.' },
     wallTime:
      { '$ref': 'Timestamp',
        hidden: true,
        description: 'UTC Timestamp.' },
     initiator: { '$ref': 'Initiator', description: 'Request initiator.' },
     redirectResponse:
      { optional: true,
        '$ref': 'Response',
        description: 'Redirect response data.' },
     type:
      { '$ref': 'Page.ResourceType',
        optional: true,
        hidden: true,
        description: 'Type of this resource.' } } }

To inspect the Network.Request (note that unlike commands and events, types are named in upper camel case) type:

>>> Network.Request
{ category: 'type',
  id: 'Request',
  type: 'object',
  description: 'HTTP request data.',
  properties:
   { url: { type: 'string', description: 'Request URL.' },
     method: { type: 'string', description: 'HTTP request method.' },
     headers: { '$ref': 'Headers', description: 'HTTP request headers.' },
     postData:
      { type: 'string',
        optional: true,
        description: 'HTTP POST request data.' },
     mixedContentType:
      { optional: true,
        type: 'string',
        enum: [Object],
        description: 'The mixed content status of the request, as defined in http://www.w3.org/TR/mixed-content/' },
     initialPriority:
      { '$ref': 'ResourcePriority',
        description: 'Priority of the resource request at the time request is sent.' } } }

Chrome Debugging Protocol versions

By default chrome-remote-interface asks the remote instance to provide its own protocol.

This behavior can be changed by setting the local option to true upon connection, in which case the local version of the protocol descriptor is used. This file is manually updated from time to time using scripts/update-protocol.sh and pushed to this repository.

To further override the above behavior there are basically two options:

  • pass a custom protocol descriptor upon connection (protocol option);

  • use the raw version of the commands and events interface to use bleeding-edge features that do not appear in the local version of the protocol descriptor;

Browser usage

This module is able to run within a web context, with obvious limitations though, namely external HTTP requests (List, New, etc.) cannot be performed directly, for this reason the user must provide a global criRequest in order to use them:

function criRequest(options, callback) {}

options is the same object used by the Node.js http module and callback is a function taking two arguments: err (JavaScript Error object or null) and data (string result).

Using webpack

It just works, simply require this module:

const CDP = require('chrome-remote-interface');

Using vanilla JavaScript

To generate a JavaScript file that can be used with a <script> element:

  1. run npm install from the root directory;

  2. manually run webpack with:

     TARGET=var npm run webpack
    
  3. use as:

    <script>
      function criRequest(options, callback) { /*...*/ }
    </script>
    <script src="chrome-remote-interface.js"></script>

TypeScript Support

TypeScript definitions are kindly provided by Khairul Azhar Kasmiran and Seth Westphal, and can be installed from DefinitelyTyped:

npm install --save-dev @types/chrome-remote-interface

API

The API consists of three parts:

CDP([options], [callback])

Connects to a remote instance using the Chrome Debugging Protocol.

options is an object with the following optional properties:

  • host: HTTP frontend host. Defaults to localhost;

  • port: HTTP frontend port. Defaults to 9222;

  • secure: HTTPS/WSS frontend. Defaults to false;

  • useHostName: do not perform a DNS lookup of the host. Defaults to false;

  • alterPath: a function taking and returning the path fragment of a URL before that a request happens. Defaults to the identity function;

  • target: determines which target this client should attach to. The behavior changes according to the type:

    • a function that takes the array returned by the List method and returns a target or its numeric index relative to the array;
    • a target object like those returned by the New and List methods;
    • a string representing the raw WebSocket URL, in this case host and port are not used to fetch the target list, yet they are used to complete the URL if relative;
    • a string representing the target id.

    Defaults to a function which returns the first available target according to the implementation (note that at most one connection can be established to the same target);

  • protocol: Chrome Debugging Protocol descriptor object. Defaults to use the protocol chosen according to the local option;

  • local: a boolean indicating whether the protocol must be fetched remotely or if the local version must be used. It has no effect if the protocol option is set. Defaults to false.

These options are also valid properties of all the instances of the CDP class. In addition to that, the webSocketUrl field contains the currently used WebSocket URL.

callback is a listener automatically added to the connect event of the returned EventEmitter. When callback is omitted a Promise object is returned which becomes fulfilled if the connect event is triggered and rejected if the error event is triggered.

The EventEmitter supports the following events:

Event: 'connect'

function (client) {}

Emitted when the connection to the WebSocket is established.

client is an instance of the CDP class.

Event: 'error'

function (err) {}

Emitted when http://host:port/json cannot be reached or if it is not possible to connect to the WebSocket.

err is an instance of Error.

CDP.Protocol([options], [callback])

Fetch the Chrome Debugging Protocol descriptor.

options is an object with the following optional properties:

  • host: HTTP frontend host. Defaults to localhost;
  • port: HTTP frontend port. Defaults to 9222;
  • secure: HTTPS/WSS frontend. Defaults to false;
  • useHostName: do not perform a DNS lookup of the host. Defaults to false;
  • alterPath: a function taking and returning the path fragment of a URL before that a request happens. Defaults to the identity function;
  • local: a boolean indicating whether the protocol must be fetched remotely or if the local version must be returned. Defaults to false.

callback is executed when the protocol is fetched, it gets the following arguments:

When callback is omitted a Promise object is returned.

For example:

const CDP = require('chrom 

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap