Инструментирование Google Chrome через WebSocket API

в 18:18, , рубрики: chrome, chrome developer tools, chrome devtools, Google Chrome, remote debug, ruby, webdriver, webkit, WebSocket, websockets, Веб-разработка, отладка, удаленная отладка

image Взаимодействие с браузерами никогда не было работой для слабонервных: около полудюжины различных API, различные механизмы IPC, и разные возможности у разных поставщиков. Такие проекты, как WebDriver, пытаются абстрагироваться от этой сложности, к тому же в Сети можно найти десятки других «безголовых» драйверов, использующих WebKit или иные движки. В настоящее время в работе даже находится спецификация W3C на WebDriver.

Инструментирование Google Chrome

Тем не менее, в то время, как создание общего решения является сложной задачей, оказалось, что инструментирование Chrome очень просто, — как я недавно обнаружил при исследовании некоторых вопросов, связанных с сетевыми задержками. Начиная с 18 версии, Chrome теперь поддерживает протокол удалённой отладки v1.0, который предоставляет все возможности браузера с помощью обычного WebSocket!

/Applications/Path To/Google Chrome --remote-debugging-port=9222 # OSX
$> curl localhost:9222/json

[ {
   "devtoolsFrontendUrl": "/devtools/devtools.html?host=localhost:9222&page=1",
   "faviconUrl": "",
   "thumbnailUrl": "/thumb/chrome://newtab/",
   "title": "New Tab",
   "url": "chrome://newtab/",
   "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/1"
} ]


Сперва мы включаем возможность удалённой отладки в Chrome (по умолчанию выключено). С этого момента Chrome предоставляет HTTP-сервер, который позволяет контролировать все открытые вкладки. Каждая вкладка представляет собой изолированный процесс и, следовательно, работает со своим WebSocket, путь к которому доступен через атрибут webSocketDebuggerUrl. Давайте попробуем сделать что-нибудь с этим:

require 'em-http'
require 'faye/websocket'
require 'json'

EM.run do
  # Chrome runs an HTTP handler listing available tabs
  conn = EM::HttpRequest.new('http://localhost:9222/json').get
  conn.callback do
    resp = JSON.parse(conn.response)
    puts "#{resp.size} available tabs, Chrome response: n#{resp}"

    # connect to first tab via the WS debug URL
    ws = Faye::WebSocket::Client.new(resp.first['webSocketDebuggerUrl'])
    ws.onopen = lambda do |event|
      # once connected, enable network tracking
      ws.send JSON.dump({id: 1, method: 'Network.enable'})

      # tell Chrome to navigate to twitter.com and look for "chrome" tweets
      ws.send JSON.dump({
        id: 2,
        method: 'Page.navigate',
        params: {url: 'http://twitter.com/#!/search/chrome?q=chrome&' + rand(100).to_s}
      })
    end

    ws.onmessage = lambda do |event|
      # print event notifications from Chrome to the console
      p [:new_message, JSON.parse(event.data)]
    end
  end
end

В этом примере мы говорим Chrome, чтобы он включил отслеживание и нотификации сетевого трафика, а затем говорим ему, что нужно выполнить поиск в Twitter. При этом Chrome будет направлять нам десятки уведомлений сети: начальная выборка страницы, уведомления для каждого подресурса, XHR, и так далее (например, событие Network.responseReceived). На самом деле, если вы оставите Web-страницу открытой, вы также увидите события длительного опроса (long polling), генерируемые для получения новых твитов. Тонны информации, все в вашем распоряжении.

Удаленная отладка (и более того) с Chrome

Приведенный выше пример иллюстрирует очень простое взаимодействие с Network API, но протокол предоставляет гораздо больше возможностей. Вы можете работать с отладчиком JavaScript, управлять виртуальной машиной V8, модифицировать и изучать DOM, а также отслеживать хронологию событий, а ещё более чем полдюжины других возможностей. Наконец, хотя круто управлять настольным браузером, управлением браузером на вашем телефоне ещё круче: Chrome для Android предоставляет все те же возможности.

Автор: akzhan


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js