JS检测浏览器开发者工具是否打开

在有些情况下 我们需要检测用户是否打开了浏览器的开发者工具 右键检查出来的就是开发者工具 比如前端爬虫检测 或者是避免用户非法篡改信息 本篇文章主要讲述几种前端js检测开发者工具是否打开的方法
《JS检测浏览器开发者工具是否打开》

1.重写toString()

对于一些浏览器,比如Chrome、FireFox,如果控制台输出的是对象,则保留对象的引用,每次打开开发者工具的时候都会重新调用一下对象的toString()方法将返回结果打印到控制台(console tab)上。

所以只需要创建一个对象,重写它的toString()方法,然后在页面初始化的时候就将其打印在控制台上(这里假设控制台还没有打开),当用户打开控制台时会再去调用一下这个对象的toString()方法,用户打开控制台的行为就会被捕获到。

下面是一个小小的例子,当Chrome用户的开发者工具状态从关闭向打开转移时,这个动作会被捕获到并交由回调函数处理:

<html>
<head>
    <title>console detect test</title>
</head>
<body>
<script>
 
    /** * 控制台打开的时候回调方法 */
    function consoleOpenCallback(){ 
        alert("CONSOLE OPEN");
        return "";
    }
 
    /** * 立即运行函数,用来检测控制台是否打开 */
    !function () { 
        // 创建一个对象
        let foo = /./;
        // 将其打印到控制台上,实际上是一个指针
        console.log(foo);
        // 要在第一次打印完之后再重写toString方法
        foo.toString = consoleOpenCallback;
    }()
 
</script>
</body>
</html>

《JS检测浏览器开发者工具是否打开》
测试环境火狐

二、debugger

类似于代码里的断点,浏览器在打开开发者工具时(对应于代码调试时的debug模式)检测到debugger标签(相当于是程序中的断点)的时候会暂停程序的执行:

《JS检测浏览器开发者工具是否打开》
此时需要点一下那个蓝色的“Resume script execution”程序才会继续执行,这中间会有一定的时间差,通过判断这个时间差大于一定的值就认为是打开了开发者工具。这个方法并不会误伤,当没有打开开发者工具时遇到debugger标签不会暂停,所以这种方法还是蛮好的,而且通用性比较广。

下面是一个使用debugger标签检测开发者工具是否打开的例子:

<html>
<head></head>
<body>
<script>
 
    function consoleOpenCallback() { 
        alert("CONSOLE OPEN");
    }
 
    !function () { 
        const handler = setInterval(() => { 
            const before = new Date();
            debugger;
            const after = new Date();
            const cost = after.getTime() - before.getTime();
            if (cost > 100) { 
                consoleOpenCallback();
                clearInterval(handler)
            }
        }, 1000)
    }();
 
</script>
</body>
</html>

《JS检测浏览器开发者工具是否打开》

三、检测窗口大小

检测窗口大小比较简单,首先要明确两个概念,窗口的outer大小和inner大小:

window.innerWidth / window.innerHeight :可视区域的宽高,window.innerWidth包含了纵向滚动条的宽度,window.innerHeight包含了水平(横向)滚动条的宽度。

window.outerWidth / window.outerHeight:会在innerWidth和innerHeight的基础上加上工具条的宽度。

关于检测窗口大小,不再自己写例子,有人专门针对此写了个库:https://github.com/sindresorhus/devtools-detect,毕竟几百个star,比我这个渣渣写的好多了,代码比较简单,使用部分其github都有说明,这里只对其核心代码做个分析,此处贴出鄙人对此库核心代码的分析:

/* eslint-disable spaced-comment */
/*! devtools-detect Detect if DevTools is open https://github.com/sindresorhus/devtools-detect by Sindre Sorhus MIT License comment by CC11001100 */
(function () { 
    'use strict';
    var devtools = { 
        open: false,
        orientation: null
    };
    // inner大小和outer大小超过threshold被认为是打开了开发者工具
    var threshold = 160;
    // 当检测到开发者工具后发出一个事件,外部监听此事件即可,设计得真好,很好的实现了解耦
    var emitEvent = function (state, orientation) { 
        window.dispatchEvent(new CustomEvent('devtoolschange', { 
            detail: { 
                open: state,
                orientation: orientation
            }
        }));
    };
 
    // 每500毫秒检测一次开发者工具的状态,当状态改变时触发事件
    setInterval(function () { 
        var widthThreshold = window.outerWidth - window.innerWidth > threshold;
        var heightThreshold = window.outerHeight - window.innerHeight > threshold;
        var orientation = widthThreshold ? 'vertical' : 'horizontal';
 
        // 第一个条件判断没看明白,heightThreshold和widthThreshold不太可能同时为true,不论是其中任意一个false还是两个都false取反之后都会为true,此表达式恒为true
        if (!(heightThreshold && widthThreshold) &&
            // 针对Firebug插件做检查
            ((window.Firebug && window.Firebug.chrome && window.Firebug.chrome.isInitialized) || widthThreshold || heightThreshold)) { 
            // 开发者工具打开,如果之前开发者工具没有打开,或者已经打开但是靠边的方向变了才会发送事件
            if (!devtools.open || devtools.orientation !== orientation) { 
                emitEvent(true, orientation);
            }
 
            devtools.open = true;
            devtools.orientation = orientation;
        } else { 
            // 开发者工具没有打开,如果之前处于打开状态则触发事件报告状态
            if (devtools.open) { 
                emitEvent(false, null);
            }
 
            // 将标志位恢复到未打开
            devtools.open = false;
            devtools.orientation = null;
        }
    }, 500);
 
    if (typeof module !== 'undefined' && module.exports) { 
        module.exports = devtools;
    } else { 
        window.devtools = devtools;
    }
 
})();

缺点:

  1. 使用window属性检查大小可能会有浏览器兼容性问题,因为不是专业前端只测试了Chrome和ff是没有问题的。

  2. 此方案还是有漏洞的,就拿Chrome浏览器来说,开发者工具窗口有四个选项:单独窗口、靠左、靠下、靠右。

  3. 靠左、靠右、靠下都会占用当前窗口的一些空间,这种情况会被检测到,但是独立窗口并不会占用打开网页窗口的空间,所以这种情况是检测不到的,可去此页面进行验证:https://sindresorhus.com/devtools-detect/。
    详细内容参考: https://www.cnblogs.com/cc11001100/p/9265945.html

    原文作者:沉迷...
    原文地址: https://blog.csdn.net/weixin_42343307/article/details/121258832
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞