1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
# Headless Chromium
Headless Chromium allows running Chromium in a headless/server environment.
Expected use cases include loading web pages, extracting metadata (e.g., the
DOM) and generating bitmaps from page contents -- using all the modern web
platform features provided by Chromium and Blink.
There are two ways to use Headless Chromium:
## Usage via the DevTools remote debugging protocol
1. Start a normal Chrome binary with the `--headless` command line flag
(Linux-only for now):
```
$ chrome --headless --remote-debugging-port=9222 https://chromium.org
```
Currently you'll also need to use `--disable-gpu` to avoid an error from a
missing Mesa library.
2. Navigate to `http://localhost:9222` in another browser to open the
[DevTools](https://developer.chrome.com/devtools) interface or use a tool such
as [Selenium](http://www.seleniumhq.org/) to drive the headless browser.
## Usage from Node.js
For example, the [chrome-remote-interface](https://github.com/cyrus-and/chrome-remote-interface)
Node.js package can be used to extract a page's DOM like this:
```
const CDP = require('chrome-remote-interface');
CDP((client) => {
// Extract used DevTools domains.
const {Page, Runtime} = client;
// Enable events on domains we are interested in.
Promise.all([
Page.enable()
]).then(() => {
return Page.navigate({url: 'https://example.com'});
});
// Evaluate outerHTML after page has loaded.
Page.loadEventFired(() => {
Runtime.evaluate({expression: 'document.body.outerHTML'}).then((result) => {
console.log(result.result.value);
client.close();
});
});
}).on('error', (err) => {
console.error('Cannot connect to browser:', err);
});
```
## Usage as a C++ library
Headless Chromium can be built as a library for embedding into a C++
application. This approach is otherwise similar to controlling the browser over
a DevTools connection, but it provides more customization points, e.g., for
networking and [mojo services](https://docs.google.com/document/d/1Fr6_DJH6OK9rG3-ibMvRPTNnHsAXPk0VzxxiuJDSK3M/edit#heading=h.qh0udvlk963d).
[Headless Example](https://cs.chromium.org/chromium/src/headless/app/headless_example.cc)
is a small sample application which demonstrates the use of the headless C++
API. It loads a web page and outputs the resulting DOM. To run it, first
initialize a headless build configuration:
```
$ mkdir -p out/Debug
$ echo 'import("//build/args/headless.gn")' > out/Debug/args.gn
$ gn gen out/Debug
```
Then build the example:
```
$ ninja -C out/Debug headless_example
```
After the build completes, the example can be run with the following command:
```
$ out/Debug/headless_example https://www.google.com
```
[Headless Shell](https://cs.chromium.org/chromium/src/headless/app/headless_shell.cc)
is a more capable headless application. For instance, it supports remote
debugging with the [DevTools](https://developer.chrome.com/devtools) protocol.
To do this, start the application with an argument specifying the debugging
port:
```
$ ninja -C out/Debug headless_shell
$ out/Debug/headless_shell --remote-debugging-port=9222 https://youtube.com
```
Then navigate to `http://localhost:9222` with your browser.
## Embedder API
The embedder API allows developers to integrate the headless library into their
application. The API provides default implementations for low level adaptation
points such as networking and the run loop.
The main embedder API classes are:
- `HeadlessBrowser::Options::Builder` - Defines the embedding options, e.g.:
- `SetMessagePump` - Replaces the default base message pump. See
`base::MessagePump`.
- `SetProxyServer` - Configures an HTTP/HTTPS proxy server to be used for
accessing the network.
## Client/DevTools API
The headless client API is used to drive the browser and interact with loaded
web pages. Its main classes are:
- `HeadlessBrowser` - Represents the global headless browser instance.
- `HeadlessWebContents` - Represents a single "tab" within the browser.
- `HeadlessDevToolsClient` - Provides a C++ interface for inspecting and
controlling a tab. The API functions corresponds to [DevTools commands](https://developer.chrome.com/devtools/docs/debugger-protocol).
See the [client API documentation](https://docs.google.com/document/d/1rlqcp8nk-ZQvldNJWdbaMbwfDbJoOXvahPCDoPGOwhQ/edit#)
for more information.
## Resources and Documentation
Mailing list: [headless-dev@chromium.org](https://groups.google.com/a/chromium.org/forum/#!forum/headless-dev)
Bug tracker: [Internals>Headless](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3AInternals%3EHeadless)
[File a new bug](https://bugs.chromium.org/p/chromium/issues/entry?components=Internals%3EHeadless) ([bit.ly/2pP6SBb](https://bit.ly/2pP6SBb))
* [Runtime headless mode on Windows OS](https://docs.google.com/document/d/12c3bSEbmpeGevuyFHcvEKw9br6CkFJSS2saQynBjIzE)
* [BeginFrame sequence numbers + acknowledgements](https://docs.google.com/document/d/1nxaunQ0cYWxhtS6Zzfwa99nae74F7gxanbuT5JRpI6Y/edit#)
* [Deterministic page loading for Blink](https://docs.google.com/document/d/19s2g4fPP9p9qmMZvwPX8uDGbb-39rgR9k56B4B-ueG8/edit#)
* [Crash dumps for Headless Chrome](https://docs.google.com/document/d/1l6AGOOBLk99PaAKoZQW_DVhM8FQ6Fut27lD938CRbTM/edit)
* [Runtime headless mode for Chrome](https://docs.google.com/document/d/1aIJUzQr3eougZQp90bp4mqGr5gY6hdUice8UPa-Ys90/edit#)
* [Virtual Time in Blink](https://docs.google.com/document/d/1y9kdt_zezt7pbey6uzvt1dgklwc1ob_vy4nzo1zbqmo/edit#heading=h.tn3gd1y9ifml)
* [Headless Chrome architecture](https://docs.google.com/document/d/11zIkKkLBocofGgoTeeyibB2TZ_k7nR78v7kNelCatUE/edit)
* [Headless Chrome C++ DevTools API](https://docs.google.com/document/d/1rlqcp8nk-ZQvldNJWdbaMbwfDbJoOXvahPCDoPGOwhQ/edit#heading=h.ng2bxb15li9a)
* [Session isolation in Headless Chrome](https://docs.google.com/document/d/1XAKvrxtSEoe65vNghSWC5S3kJ--z2Zpt2UWW1Fi8GiM/edit)
* [Headless Chrome mojo service](https://docs.google.com/document/d/1Fr6_DJH6OK9rG3-ibMvRPTNnHsAXPk0VzxxiuJDSK3M/edit#heading=h.qh0udvlk963d)
* [Controlling BeginFrame through DevTools](https://docs.google.com/document/d/1LVMYDkfjrrX9PNkrD8pJH5-Np_XUTQHIuJ8IEOirQH4/edit?ts=57d96dbd#heading=h.ndv831lc9uf0)
* [Viewport bounds and scale for screenshots](https://docs.google.com/document/d/1VTcYz4q_x0f1O5IVrvRX4u1DVd_K34IVUl1VULLTCWw/edit#heading=h.ndv831lc9uf0)
* [BlinkOn 6 presentation slides](https://docs.google.com/presentation/d/1gqK9F4lGAY3TZudAtdcxzMQNEE7PcuQrGu83No3l0lw/edit#slide=id.p)
* [Architecture design doc](https://docs.google.com/document/d/11zIkKkLBocofGgoTeeyibB2TZ_k7nR78v7kNelCatUE)
|