用JavaScript检测当前浏览器是无头浏览器

更新日期: 2020-04-20阅读: 2k标签: 浏览器

什么是无头浏览器(headless browser)?

无头浏览器是指可以在图形界面情况下运行的浏览器。我可以通过编程来控制无头浏览器自动执行各种任务,比如做测试,给网页截屏等。


为什么叫“无头”浏览器?

“无头”这个词来源于最初的“无头计算机(Headless computer)”。维基百科关于的“无头计算机”词条:

无头系统(headless system)是指已配置为无须显示器(即“头”)、键盘和鼠标操作的计算机系统或设备。无头系统通常通过网络连接控制,但也有部分无头系统的设备需要通过RS-232串行连接进行设备的管理。服务器通常采用无头模式以降低运作成本。


为什么要检测无头浏览器?

除了之前提到的两种无害的使用案例,无头浏览器可以被用来自动执行恶意任务。最常见的形式是做网络爬虫,或伪装访问量,或探测网站漏洞。

一个非常流行的无头浏览器是PhantomJS,因为它是基于 Qt 框架,所以跟我们常见的浏览器相比有很多不同的特征,因此有很多方法判断出它。

但是,从chrome 59开始,谷歌发布了一款无头谷歌浏览器。它跟PhantomJS不同,它是基于正统的谷歌浏览器开发出来的,不是基于其它的框架,这让程序很难区分出它是正常浏览器还是无头浏览器。

下面,我们将介绍几种判断程序是运行在普通浏览器还是无头浏览器里的方法。


检测无头浏览器

注意:这些方法只是在四种设备 (2 Linux, 2 Mac) 里测试过,也就是说, 肯定还有其他很多方法检测无头浏览器。


User agent

先介绍使用做最常见的一种判断浏览器种类的方法,检查User agent。在linux计算机里Chrome version 59无头浏览器的User agent值是:

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

于是,我们可以这样检测是否是无头Chrome浏览器:

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

User agent 也可以从 HTTP headers 里获取。然而,这两种情况都很容易伪造。


插件 Plugins

navigator.plugins 会返回一个数组,里面是当前浏览器里的插件信息。通常,普通Chrome浏览器有一些缺省插件,比如 Chrome PDF viewer 或 Google Native Client。相反,在无头模式里,没有任何插件,返回的是个空数组。

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

 

语言

在谷歌浏览器里,有两个JavaScript属性可以获取当前浏览器的语言设置: navigator.language 和 navigator.languages。头一个是指浏览器界面的语言,后一个返回的是个数组,里面存储的是浏览器用户的所有次选语言。然而,在无头模式里,navigator.languages 返回的是个空字符串。

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

 

WebGL

WebGL 提供了一组能在HTML canvas 里执行3D渲染的api。通过这些API,我们可以查询出图形驱动的 vendor 和 renderer 。

在linux上的普通谷歌浏览器里,我们获得的 renderer 和 vendor 值为: “Google SwiftShader” 和 “Google Inc.”。

而在无头模式里,我们获得的一个是 “Mesa OffScreen”——它是没有使用任何 window 系统的渲染技术的名称,和 “Brian Paul” ——开源 Mesa 图形库的最初的程序。

 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");
 }

并不是所有版本的无头浏览器都有同样的这两个值。然而目前在无头浏览器里是“Mesa Offscreen” 和 “Brian Paul” 这两个值。


浏览器特征

Modernizr 可以探测出当前浏览器对HTML和css各种特性的支持程度。我发现,普通Chrome和无头Chrome里唯一的区别是,无头模式下没有 hairline 特征,它是用来检测是否支持 hidpi/retina hairlines的

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


加载失败的图片

最后,我发现的最后一个方法,也是看起来最有效的方法,切入点是检查浏览器里不能正常加载的图片的高和宽。

在正常的Chrome里,未成功加载的图片的大小跟浏览器的zoom有关,但肯定不是零。而在无头Chrome浏览器里,这种图片的宽和高都是0。

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

链接: https://www.fly63.com/article/detial/9331

浏览器禁用了javascript,各种浏览器如何开启javascript的方法总汇

您的浏览器禁用了JS脚本运行,请启用该功能。怎么解除浏览器禁用js?这篇文章将总结整理各个浏览器如何开启、禁用javascript的方法总汇。

浏览器的回流与重绘 (Reflow & Repaint)

浏览器使用流式布局模型 (Flow Based Layout)。浏览器会把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合并就产生了Render Tree。有了RenderTree,我们就知道了所有节点的样式,然后计算他们在页面上的大小和位置,最后把节点绘制到页面上。

IE6浏览器有哪些常见的bug,以及解决IE6常用bug的方法

IE6不支持min-height,解决办法使用css hack,ol内li的序号全为1,不递增。解决方法:为li设置样式display: list-item;定位父元素overflow: auto;,包含position: relative;子元素,子元素高于父元素时会溢出。解决办法:

css重设样式_清除浏览器的默认样式

由于不同的浏览器默认的样式也不同,所以在网页开发前设置一个公用样式,来清除各个浏览器的默认样式,已达到做的网页在各个浏览器中达到统一。

浏览器访问一个网站所经历的步骤

浏览器访问网站的步骤:Chrome搜索自身的DNS缓存、读取本地HOST文件、浏览器发起一个DNS的一个系统调用、浏览器获得域名对应的IP地址后,发起HTTP三次握手、TCP/IP连接建立起来、服务器端接受到了这个请求、浏览器根据拿到的资源对页面进行渲染

一个新式的基于文本的浏览器 Browsh

Browsh是一个纯文本浏览器,可以运行在大多数的TTY终端环境和任何浏览器。目前,终端客户端比浏览器客户端更先进。终端客户端即时更新和交付,以便于体验新的功能,例如,你可以观看视频。

浏览器内核有哪些?主流浏览器的所使用的内核介绍

一般说的浏览器内核是指浏览器最重要的核心部分,RenderingEngine,翻译成中文大概意思就是“解释引擎”,我们一般称为浏览器内核。由于不同的内核各自有一套自己的渲染网页和解释页面代码的机制,所以就会有一些问题存在。

程序员眼中的浏览器是什么样的?IE:有本事你卸了我啊

主流浏览器之争从上个世纪开就开始,已经持续了很长的时间。人们都在笑话IE,纷纷转向其它浏览器。今天,我向大家分享一下针对IE的搞笑图片,只是逗乐而已,喝杯咖啡,坐下来慢慢享受吧。

精打细算浏览器空闲时间

有时候我们希望在浏览器中执行一些低优先级的任务,比如记录统计数据、做一些耗时的数据处理等,暂且将其称为后台任务。这些任务跟动画计算、合成帧、响应用户输入等高优先级的任务共享主线程

深入浏览器事件循环的本质

浏览器的事件循环,前端再熟悉不过了,每天都会接触的东西。但我以前一直都是死记硬背:事件任务队列分为macrotask和microtask,浏览器先从macrotask取出一个任务执行,再执行microtask内的所有任务,接着又去macrotask取出一个任务执行

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!