How to use JavaScript to detect whether the current browser is headless

  • What is a headless browser?
  • Why is it called “headless” browser?
  • Why should headless browsers be detected?
  • Detect headless browser
  • User agent
  • Plugins
  • language
  • WebGL
  • Browser features
  • Failed to load pictures

What is a headless browser?

Headless browser refers to a browser that can run in a graphical interface. I can control the headless browser to automatically perform various tasks through programming, such as testing, screenshots of web pages, etc.

Why is it called “headless” browser?

The word “headless” comes from the original “headless computer”. Wikipedia entry for “headless computer”:

Headless system refers to a computer system or device that has been configured to operate without a display (i.e. “head”), keyboard and mouse. Headless system is usually controlled through network connection, but some headless system devices need to be managed through RS-232 serial connection. Servers usually adopt headless mode to reduce operating costs.

Why should headless browsers be detected?

In addition to the two harmless use cases mentioned earlier, headless browsers can be used to automate malicious tasks. The most common form is to do web crawlers, or disguise traffic, or detect website vulnerabilities.

A very popular headless browser is phantomjs. Because it is based on the QT framework, it has many different features compared with our common browsers, so there are many ways to judge it.

However, starting with chrome 59, Google released a headless Google browser. Unlike phantomjs, it is developed based on the orthodox Google browser, not on other frameworks, which makes it difficult for the program to distinguish whether it is a normal browser or a headless browser.

Next, we will introduce several methods to determine whether the program is running in an ordinary browser or a headless browser.

Detect headless browser

Note: these methods have only been tested on four devices (2 Linux, 2 MAC). In other words, there must be many other methods to detect headless browsers.

User agent

First, introduce the most common method to judge the browser type, and check the user agent. In Linux computer, the user agent value of chrome version 59 headless browser is:

“Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (Khtml, like Gecko) HeadlessChrome/59.0.3071.115 Safari/537.36”

Therefore, we can check whether it is a headless Chrome browser:

if (/HeadlessChrome/.test(window.navigator.userAgent)) {
  console.log("Chrome headless detected");

User agent can also be obtained from HTTP headers. However, both cases are easy to fabricate.


navigator. Plugins will return an array containing the plug-in information in the current browser. Generally, ordinary chrome browsers have some default plug-ins, such as chrome PDF viewer or Google native client. In contrast, in headless mode, there is no plug-in and an empty array is returned.

if(navigator.plugins.length == 0) {
  console.log("It may be Chrome headless");


In Google browser, there are two JavaScript attributes that can get the language settings of the current browser: navigator Language and navigator languages。 The first one refers to the language of the browser interface. The second one returns an array containing all the secondary languages selected by the browser user. However, in headless mode, navigator Languages returns an empty string.

if(navigator.languages == "") {
  console.log("Chrome headless detected");


Webgl provides a set of APIs that can perform 3D rendering in htmlcanvas. Through these APIs, we can query graph driven vendors and renderers.

In the ordinary Google browser on Linux, the renderer and vendor values we get are “Google swiftshader” and “Google Inc.”.

In headless mode, we obtained “mesa offscreen” – the name of the rendering technology that does not use any window system, and “Brian Paul” – the original program of the open source mesa graphics library.

 var canvas = document.createElement('canvas');
 var gl = canvas.getContext('webgl');
 var debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
 var vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
 var renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
 if(vendor == "Brian Paul" && renderer == "Mesa OffScreen") {
  console.log("Chrome headless detected");

Not all versions of headless browsers have the same two values. However, in the headless browser, there are two values: “mesa offscreen” and “Brian Paul”

Browser features

Modernizr can detect the current browser’s support for various features of HTML and CSS. I found that the only difference between ordinary chrome and headless Chrome is that there is no hairline feature in headless mode. It is used to detect whether hidpi/retina hairlines are supported

if(!Modernizr["hairline"]) {
  console.log("It may be Chrome headless");

Failed to load pictures

Finally, the last method I found, which seems to be the most effective method, is to check the height and width of images that cannot be loaded normally in the browser.

In normal chrome, the size of the pictures that fail to load is related to the browser’s zoom, but it is certainly not zero. In headless chrome, the width and height of this image are 0.

var body = document.getElementsByTagName("body")[0];
var image = document.createElement("img");
image.src = "http://iloveponeydotcom32188.jg";
image.setAttribute("id", "fakeimage");
image.onerror = function(){
	if(image.width == 0 && image.height == 0) {
		console.log("Chrome headless detected");

The above is how to use JavaScript to detect that the current browser is a headless browser. For more information about JavaScript, please pay attention to other developeppaer related articles!

Recommended Today

C#/VB. Net to convert HTML of web page file into PDF document

HTML (Hypertext Markup Language) is a markup language commonly used to display web pages, and HTML file is the file format corresponding to this markup language, and the vast majority of web page files adopt this format. However, HTML files may have different typesetting and display effects on different devices and platforms. If we want […]