Узнайте, открыта ли консоль Chrome

Я использую этот маленький скрипт, чтобы узнать, открыт ли Firebug:

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

И это хорошо работает. Теперь я искал полчаса, чтобы найти способ определить, открыта ли встроенная консоль веб-разработчика Google Chrome, но я не смог найти подсказки.

Это:

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

не работает

РЕДАКТИРОВАТЬ:

Таким образом, кажется, что невозможно определить, открыта ли консоль Chrome. Но есть " взлом", который работает, с некоторыми недостатками:

  • не будет работать, когда консоль отстыкована
  • не будет работать, когда консоль открыта при загрузке страницы

Итак, я сейчас выберу ответ Unsigned, но если у кого-нибудь возникнет блестящая идея, он может ответить, и я изменю выбранный ответ! Спасибо!

25 ответов

Решение

ToString (2017-2018)

Поскольку первоначального автора больше не существует, и это все еще принятый ответ, добавив это решение для наглядности. zswang Antonin Hildebrand за комментарий к zswang. Это решение использует тот факт, что 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)

Обновить: console.profiles был удален из Chrome. Это решение больше не работает.

Спасибо Paul Irish Айришу ( Paul Irish за то, что он указал на это решение от Discover 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');
}

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 получат его идентификатор

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

Очень надежный взлом

В основном установите 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);
});

Я создал 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.

      console.log(Object.defineProperties(new Error, {
  message: {get() {alert('Chrome/Firefox')}},
  toString: {value() {(new Error).stack.includes('toString@')&&alert('Safari')}}
}));

Демо: https://jsbin.com/cateqeyono/edit?html, вывод

Я нашел способ узнать, открыта ли консоль Chrome или нет. Это все еще хак, но он более точен и будет работать, если консоль отстыкована или нет.

В основном выполнение этого кода с закрытой консолью занимает около ~100 микросекунд, а при открытой консоли - примерно в два раза больше ~200 микросекунд.

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

(1 миллисекунда = 1000 микросекунд)

Я написал больше об этом здесь.

Демо здесь.


Обновить:

@zswang нашел наилучшее на данный момент решение - зацените его ответ

Вот решение, над которым я работал над Chrome и Firefox (сегодня 22 июля 2021 года): https://github.com/david-fong/detect-devtools-via-debugger-heartstop.

Позже протестирую в Safari.

Скопировано из ридми:

Он открывает веб-воркер с циклом опроса, который отправляет импульсы в основной поток. Каждый импульс - это два сообщения с оператором отладчика между ними, который создаст ненормальную задержку между вложенными сообщениями, когда инструменты разработчика открываются в любом браузере, который реализует рабочие процессы отладки и позволяет отладку всегда, если и только если инструменты разработки открыты. Он не блокирует основной поток.

Более подробная информация о плюсах и минусах, а также о том, кому следует и не следует его использовать, находится в readme.

Если ваша цель - заклинить инструменты разработчика, попробуйте это (я нашел более сложную версию в месте, где код JS был запутан, это очень раздражает):

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

Я обнаружил, что в Chrome 89 работают новые методы

Используя console.profile, setInterval и функцию toString

          var devtools = function() {};
    devtools.toString = function() {
        alert('NOPE!!')
        return '-'
    }

    setInterval(()=>{
        console.profile(devtools)
        console.profileEnd(devtools)
    }, 1000)

В сафари не работает.

Ниже хром 89, я не могу проверить, работает ли он.

Я написал сообщение в блоге об этом: 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 ?")
    }
  });
});

Я нашел новый метод:

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

тест онлайн

Инструменты разработчика Chrome на самом деле являются лишь частью библиотеки WebKit WebKit. Таким образом, этот вопрос относится к Safari, Chrome и любым другим пользователям WebCore.

Если решение существует, оно будет основано на различиях в DOM, когда веб-инспектор WebKit открыт и когда он закрыт. К сожалению, это своего рода проблема курицы и яйца, потому что мы не можем использовать инспектора для наблюдения за DOM, когда инспектор закрыт.

То, что вы можете сделать, это написать немного JavaScript для вывода всего дерева DOM. Затем запустите его один раз, когда инспектор открыт, и один раз, когда инспектор закрыт. Любое различие в DOM, вероятно, является побочным эффектом веб-инспектора, и мы можем использовать его для проверки, проверяет пользователь или нет.

Эта ссылка является хорошим началом для сценария дампа DOM, но вы захотите полностью DOMWindow объект, а не просто document,

Обновить:

Похоже, есть способ сделать это сейчас. Проверьте Chrome Inspector Detector

Есть хитрый способ проверить его на наличие расширений с разрешением "вкладки":

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){ ... })

Подход Мухаммада Умера сработал для меня, и я использую React, поэтому я решил создать решение для хуков:

const useConsoleOpen = () => {
  const [consoleOpen, setConsoleOpen] = useState(true)

  useEffect(() => {
    var checkStatus;

    var element = new Image();
    Object.defineProperty(element, "id", {
      get: function () {
        checkStatus = true;
        throw new Error("Dev tools checker");
      },
    });

    requestAnimationFrame(function check() {
      checkStatus = false;
      console.dir(element); //Don't delete this line!
      setConsoleOpen(checkStatus)
      requestAnimationFrame(check);
    });
  }, []);

  return consoleOpen
}

ПРИМЕЧАНИЕ: Когда я возился с этим, он не работал долгое время, и я не мог понять, почему. Я удалилconsole.dir(element);что очень важно для того, как это работает. Я удаляю большинство не описательных действий консоли, поскольку они просто занимают место и обычно не нужны функции, поэтому у меня это не сработало.

Чтобы использовать это:

import React from 'react'

const App = () => {
  const consoleOpen = useConsoleOpen()

  return (
    <div className="App">
      <h1>{"Console is " + (consoleOpen ? "Open" : "Closed")}</h1>
    </div>
  );
}

Надеюсь, это поможет любому, кто использует React. Если кто-то хочет расширить это, я хотел бы иметь возможность в какой-то момент остановить бесконечный цикл (поскольку я не использую это в каждом компоненте) и найти способ сохранить консоль в чистоте.

Открытие консоли инструментов разработчика Javascript Detect

Работает с 02.02.2022

  • Chrome версии 97 (инструменты разработчика отстыкованы / закреплены / сочетания клавиш )
  • Edge Version 97 (инструменты разработчика отстыкованы / закреплены / сочетания клавиш )
  • FireFox версии 96.0.03 (инструменты разработчика отстыкованы / закреплены / сочетания клавиш )
  • Сафари ?
  • Обнаружение FireBug (инструменты разработчика)

Когда DevTools браузера открыт, точки останова помечены как «отладчик»; будет присоединен до тех пор, пока вы не деактивируете точки останова.

Итак, вот код, чтобы проверить, включен ли отладчик:

Примечание: если используется CSP, вам нужно либо добавитьworker-src 'unsafe-inline'к политике CSP или переместить исходный код рабочего процесса, указанный выше, в ресурс, разрешенный CSP, и изменитьworkerUrlк этому ресурсу.

Также вы можете попробовать это: 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);
});

Лучший способ включить/отключить функцию Debug-Mode — установить флаг 'debugMode'='off'в localStorage по умолчанию -

      localStorage.setItem('debugMode', 'off');

Затем измените его в локальном хранилище браузера вручную на «включено» во время разработки -

Затем используйте приведенное ниже условие в коде, чтобы выполнить другое действие, если оно «включено» -

      if(localStorage.getItem('debugMode') === 'on'){
   //do something 1
}else {
   //do something 2
}

Что касается Chrome/77.0.3865.75, то версия 2019 года не работает. toString вызывается немедленно, без открытия инспектора.

const resultEl = document.getElementById('result')
const detector = function () {}

detector.toString = function () {
 resultEl.innerText = 'Triggered'
}

console.log('%c', detector)
<div id="result">Not detected</div>

Если вы разработчики, которые делают что-то во время разработки. Проверьте это расширение Chrome. Это поможет вам определить, когда Chrome Devtoos открывается или закрывается.

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

Это расширение помогает разработчикам Javascript определять, когда Chrome Devtools открыт или закрыт на текущей странице. Когда Chrome Devtools закрывается / открывается, расширение вызывает событие с именем devtoolsStatusChanged в элементе window.document.

Это пример кода:

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

Создавать цветное приветственное сообщение при каждом открытии консоли.

Некоторые ответы здесь перестанут работать в Chrome 65. Вот альтернатива временной атаки, которая довольно надежно работает в 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);

});

Временное решение (работает для состыкованного и несостыкованного)

Это немного навязчиво, но не так сильно, как ловушка отладчика.

Использовать этот пакет isDevToolsOpened()функция из пакета dev-tools-monitor, которая работает должным образом во всех браузерах, кроме firefox.

Инструменты разработчика обычно открываются профессиональным разработчиком с помощью сочетания клавиш. Вы можете обнаружить эти комбинации клавиш и поймать событие - или предотвратить открытие панели.

<script>
function devToolsOpened(e){
    alert("devtools opened");
    // uncomment to prevent opening dev.tools:
    // e.preventDefault();
}
window.addEventListener('keydown', function(e) {

    if (
        // CMD + Alt + I (Chrome, Firefox, Safari)
        e.metaKey == true && e.altKey == true && e.keyCode == 73 ||
        // CMD + Alt + J (Chrome)
        e.metaKey == true && e.altKey == true && e.keyCode == 74 ||
        // CMD + Alt + C (Chrome)
        e.metaKey == true && e.altKey == true && e.keyCode == 67 ||
        // CMD + Shift + C (Chrome)
        e.metaKey == true && e.shiftKey == true && e.keyCode == 67 ||
        // Ctrl + Shift + I (Chrome, Firefox, Safari, Edge)
        e.ctrlKey == true && e.shiftKey == true && e.keyCode == 73 ||
        // Ctrl + Shift + J (Chrome, Edge)
        e.ctrlKey == true && e.shiftKey == true && e.keyCode == 74 ||
        // Ctrl + Shift + C (Chrome, Edge)
        e.ctrlKey == true && e.shiftKey == true && e.keyCode == 67 ||
        // F12 (Chome, Firefox, Edge)
        e.keyCode == 123 ||
        // CMD + Alt + U, Ctrl + U (View source: Chrome, Firefox, Safari, Edge)
        e.metaKey == true && e.altKey == true && e.keyCode == 85 ||
        e.ctrlKey == true && e.keyCode == 85
        ){
            devToolsOpened(e);
    }
});
</script>

Сочетания клавиш для открытия инструментов разработчика:

Другие вопросы по тегам