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

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

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

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

Это:

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

не работает.

EDIT:

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

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

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

Ответ 1

функция toString (2019)

Благодарим Overcl9ck прокомментировать этот ответ. Замена регулярного выражения /./ на пустой функциональный объект все еще работает.

var devtools = function(){};
devtools.toString = function() {
  this.opened = true;
}

console.log('%c', devtools);
// devtools.opened will become true if/when the console is opened

regex toString (2017-2018)

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

Спасибо Полу Ирландскому за то, что он указал на это решение от 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');
}

Ответ 2

Хром 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);

Ответ 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.

Ответ 4

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

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

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

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

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

Демо здесь.


Update:

@zswang нашел текущее лучшее решение - проверьте его ответ

Ответ 5

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

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

Ответ 6

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

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

Ответ 7

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

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

тестирование онлайн

Ответ 8

Существует сложный способ проверить его для расширений с разрешением "tabs":

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

Ответ 9

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

Ответ 10

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

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

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

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

Update:

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

Ответ 11

Также вы можете попробовать следующее: https://github.com/sindresorhus/devtools-detect

// check if it open
console.log('is DevTools open?', window.devtools.open);
// check it orientation, null if not open
console.log('and DevTools orientation?', window.devtools.orientation);

// get notified when it 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);
});

Ответ 12

Если вы разработчики, которые делают вещи во время разработки. Проверьте это расширение 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
    }
});

Ответ 13

Некоторые ответы здесь перестанут работать в 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);

});

Ответ 14

Что касается 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>