首页 文章

了解Chrome控制台是否已打开

提问于
浏览
107

我正在使用这个小脚本来查明Firebug是否已打开:

if (window.console && window.console.firebug) {
    //is open
};

它运作良好 . 现在我正在寻找一种方法来检测Google Chrome的内置Web开发者控制台是否已打开,但我找不到任何提示 .

这个:

if (window.console && window.console.chrome) {
    //is open
};

不起作用 .

编辑:

因此,似乎无法检测Chrome控制台是否已打开 . 但是有一个“hack”可行,但有一些缺点:

控制台取消停靠后

  • 将无效
    在页面加载时打开控制台时
  • 将无效

所以,我现在要选择Unsigned的答案,但如果有人提出了一个好主意,欢迎他仍然回答我改变选定的答案!谢谢!

13 回答

  • 107

    我找到了一种方法来判断Chrome控制台是否已打开 . 它仍然是一个黑客,但它更准确,并将工作天气控制台是否解除对接 .

    基本上在控制台关闭的情况下运行此代码需要约100微秒,而控制台打开时需要大约两倍~200微秒 .

    console.log(1);
    console.clear();
    

    (1毫秒= 1000微秒)

    我写了更多关于它here .

    演示是here .


    Update:

    @zswang找到了目前最好的解决方案 - 看看他的答案

  • 2

    如果你的目标是堵塞开发人员工具,试试这个(我在JS代码被混淆的地方发现了一个更复杂的版本,这非常烦人):

    setTimeout(function() {while (true) {eval("debugger");}}, 0);
    
  • 0

    toString(2017-2018)

    由于原始提问者似乎不再存在,这仍然是可接受的答案,因此添加此解决方案以提高可见性 . 在zswanganswer上,归功于Antonin Hildebrandcomment . 此解决方案利用了以下事实:除非控制台已打开,否则不会在已记录的对象上调用 toString() .

    var devtools = /./;
    devtools.toString = function() {
      this.opened = true;
    }
    
    console.log('%c', devtools);
    // devtools.opened will become true if/when the console is opened
    

    console.profiles(2013)

    Update: console.profiles 已从Chrome中删除 . 此解决方案不再有效 .

    感谢Paul IrishDiscover DevTools指出此解决方案,使用探查器:

    function isInspectOpen()
    {
        console.profile(); 
        console.profileEnd(); 
        if (console.clear) console.clear();
        return console.profiles.length > 0;
    }
    

    window.innerHeight(2011)

    这个其他选项可以在页面加载后检测正在打开的停靠检查器,但是无法检测到未停靠的检查器,或者检查器是否已在页面加载时打开 . 误报也有一些可能性 .

    window.onresize = function()
    {
        if ((window.outerHeight - window.innerHeight) > 100)
            alert('Docked inspector was opened');
    }
    
  • 13

    Chrome 65(2018)

    r = /./
    r.toString = function () {
        document.title = '1'
    }
    console.log('%c', r);
    

    演示:https://jsbin.com/cecuzeb/edit?output(更新于2018-03-16)

    包装:https://github.com/zswang/jdetects


    打印“元素”时,Chrome开发者工具将获得其ID

    var checkStatus;
    
    var element = document.createElement('any');
    element.__defineGetter__('id', function() {
        checkStatus = 'on';
    });
    
    setInterval(function() {
        checkStatus = 'off';
        console.log(element);
        console.clear();
    }, 1000);
    

    另一个版本(来自评论)

    var element = new Image();
    Object.defineProperty(element, 'id', {
      get: function () {
        /* TODO */
        alert('囧');
      }
    });
    console.log('%cHello', element);
    

    打印常规变量:

    var r = /./;
    r.toString = function() {
      document.title = 'on';
    };
    console.log(r);
    
  • 3

    我创建了devtools-detect来检测DevTools何时打开:

    console.log('is DevTools open?', window.devtools.open);
    

    您还可以收听活动:

    window.addEventListener('devtoolschange', function (e) {
        console.log('is DevTools open?', e.detail.open);
    });
    

    当DevTools未对接时它不起作用 . 但是,适用于Chrome / Safari / Firefox DevTools和Firebug .

  • 5

    如果您是开发人员在开发期间做的事情 . 查看此Chrome扩展程序 . 它可以帮助您检测Chrome Devtoos何时打开或关闭 .

    https://chrome.google.com/webstore/detail/devtools-status-detector/pmbbjdhohceladenbdjjoejcanjijoaa?authuser=1

    此扩展程序可帮助Javascript开发人员检测Chrome Devtools何时在当前页面上打开或关闭 . 当Chrome Devtools关闭/打开时,扩展程序将在window.document元素上引发名为'devtoolsStatusChanged'的事件 .

    这是示例代码:

    function addEventListener(el, eventName, handler) {
        if (el.addEventListener) {
            el.addEventListener(eventName, handler);
        } else {
            el.attachEvent('on' + eventName,
                function() {
                    handler.call(el);
                });
        }
    }
    
    
    // Add an event listener.
    addEventListener(document, 'devtoolsStatusChanged', function(e) {
        if (e.detail === 'OPENED') {
            // Your code when Devtools opens
        } else {
            // Your code when Devtools Closed
        }
    });
    
  • 6

    我发现了一种新方法:

    var b=new Blob()
    Object.defineProperty(b,'size',{get(){
        alert('The devtool was opened!')
    }})
    setTimeout(function(){console.log(b)},3000)
    

    test online

  • 1

    你也可以试试这个:https://github.com/sindresorhus/devtools-detect

    // check if it's open
    console.log('is DevTools open?', window.devtools.open);
    // check it's orientation, null if not open
    console.log('and DevTools orientation?', window.devtools.orientation);
    
    // get notified when it's opened/closed or orientation changes
    window.addEventListener('devtoolschange', function (e) {
        console.log('is DevTools open?', e.detail.open);
        console.log('and DevTools orientation?', e.detail.orientation);
    });
    
  • 58

    有一个棘手的方法来检查它是否具有“标签”权限的扩展:

    chrome.tabs.query({url:'chrome-devtools://*/*'}, function(tabs){
        if (tabs.length > 0){
            //devtools is open
        }
    });
    

    您还可以检查它是否为您的页面打开:

    chrome.tabs.query({
        url: 'chrome-devtools://*/*',
        title: '*example.com/your/page*'
    }, function(tabs){ ... })
    
  • 3

    非常可靠的黑客

    基本上在属性上设置一个getter并将其记录在控制台中 . 显然只有在控制台打开时才能访问该东西 .

    https://jsfiddle.net/gcdfs3oo/44/

    var checkStatus;
    
    var element = new Image();
    Object.defineProperty(element, 'id', {
      get:function() {
        checkStatus='on';
        throw new Error("Dev tools checker");
      }
    });
    
    requestAnimationFrame(function check() {
        checkStatus = 'off';
        console.dir(element);
        document.querySelector('#devtool-status').innerHTML = checkStatus;
        requestAnimationFrame(check);
    });
    
  • 18

    我写了一篇关于此的博文:http://nepjua.org/check-if-browser-console-is-open/

    它可以检测它是停靠还是未停靠

    function isConsoleOpen() {  
      var startTime = new Date();
      debugger;
      var endTime = new Date();
    
      return endTime - startTime > 100;
    }
    
    $(function() {
      $(window).resize(function() {
        if(isConsoleOpen()) {
            alert("You're one sneaky dude, aren't you ?")
        }
      });
    });
    
  • 2

    这里的一些答案将停止在Chrome 65中运行.Here's a timing attack alternative在Chrome中非常可靠,并且比 toString() 方法更难缓解 . 不幸的是,它在Firefox中并不可靠 .

    addEventListener("load", () => {
    
    var baseline_measurements = [];
    var measurements = 20;
    var warmup_runs = 3;
    
    const status = document.documentElement.appendChild(document.createTextNode("DevTools are closed"));
    const junk = document.documentElement.insertBefore(document.createElement("div"), document.body);
    junk.style.display = "none";
    const junk_filler = new Array(1000).join("junk");
    const fill_junk = () => {
      var i = 10000;
      while (i--) {
        junk.appendChild(document.createTextNode(junk_filler));
      }
    };
    const measure = () => {
        if (measurements) {
        const baseline_start = performance.now();
        fill_junk();
        baseline_measurements.push(performance.now() - baseline_start);
        junk.textContent = "";
        measurements--;
        setTimeout(measure, 0);
      } else {
        baseline_measurements = baseline_measurements.slice(warmup_runs); // exclude unoptimized runs
        const baseline = baseline_measurements.reduce((sum, el) => sum + el, 0) / baseline_measurements.length;
    
        setInterval(() => {
          const start = performance.now();
          fill_junk();
          const time = performance.now() - start;
          // in actual usage you would also check document.hasFocus()
          // as background tabs are throttled and get false positives
          status.data = "DevTools are " + (time > 1.77 * baseline ? "open" : "closed");
          junk.textContent = "";
        }, 1000);
      }
    };
    
    setTimeout(measure, 300);
    
    });
    
  • 0

    Chrome开发人员工具实际上只是WebKit WebCore库的一部分 . 所以这个问题适用于Safari,Chrome和任何其他WebCore消费者 .

    如果存在解决方案,那么当WebKit Web检查器打开以及关闭时,它将基于DOM的差异 . 不幸的是,这是一种鸡和蛋的问题,因为我们不能在检查员关闭时使用检查员来观察DOM .

    您可以做的是编写一些JavaScript来转储整个DOM树 . 然后在检查员打开时运行一次,在检查员关闭时运行一次 . DOM中的任何差异可能是Web检查员的副作用,我们可以使用它来测试用户是否正在检查 .

    这个link是DOM转储脚本的一个好的开始,但是你想要转储整个 DOMWindow 对象,而不仅仅是 document .

    Update:

    看起来现在有办法做到这一点 . 查看Chrome Inspector Detector

相关问题