Chromeコンソールが開いているかどうかを確認する


141

私はこの小さなスクリプトを使用して、Firebugが開いているかどうかを調べています。

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

そしてそれはうまくいきます。現在、Google Chromeの組み込みのWeb開発者コンソールが開いているかどうかを検出する方法を見つけるために30分を探していましたが、ヒントは見つかりませんでした。

この:

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

動作しません。

編集:

そのため、Chromeコンソールが開いているかどうかを検出できないようです。しかし、機能する「ハック」があり、いくつかの欠点があります。

  • コンソールがドッキングされていない場合は機能しません
  • ページの読み込み時にコンソールが開いていると機能しません

それで、今のところUnsignedの回答を選択しますが、some1が素晴らしいアイデアを思いついた場合、彼は引き続き回答することができ、選択した回答を変更します!ありがとう!



回答の解決策は機能するようですが、コンソールがドッキングされている場合に限られます。また、Firebugスクリプトにはこの問題がなく、常に動作しているように見えますが、ページの読み込み時にコンソールがすでに開いている場合は動作しません。しかし、私は今のところそれで暮らすことができます!@pimvdbに感謝します!! とにかく問題を開いたままにし、Firebugスクリプトに似た方法を見つけて、常に機能するようにします。
r0skar 2011年

エラーをスローして.messageがフェッチされるかどうか(メッセージが表示されてデバッガーが開いているときに発生します)を確認しようとしましたが、残念ながら、これはデバッガーが開いていないときにも発生します。これが存在する場合、ハッキングについて知りたいのですが…
pimvdb '18

4
@Spudleyなぜそれが必要なのか、また説明を始めたくないという質問には関係ありません。some1のデバッグを防ぐ方法がないことは知っていますが、それは私がやろうとしていることではありません。コンソールが開いているかどうかを確認する方法を見つけようとしています。それだけです:)
r0skar

1
JFYI console.profilesメソッドが最近コンソールAPIから削除されましたsrc.chromium.org/viewvc/blink?view=revision&revision=151136
loislo

回答:


97

requestAnimationFrame(2019年後半)

これらの以前の回答は、ここでは歴史的なコンテキストとして残しておきます。現在、Muhammad UmerのアプローチはChrome 78で機能し、クローズイベントとオープンイベントの両方を検出できるという利点があります。

関数toString(2019)

この回答に対するOvercl9ckのコメントへの謝辞 /./空の関数オブジェクトで正規表現を置き換えることは引き続き機能します。

var devtools = function() {};
devtools.toString = function() {
  if (!this.opened) {
    alert("Opened");
  }
  this.opened = true;
}

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

正規表現toString(2017-2018)

元の質問者はもう存在していないようで、これはまだ受け入れられている答えなので、可視性のためにこのソリューションを追加します。クレジットはzswang答えに対するAntonin Hildebrandコメント行きます。このソリューションはtoString()、コンソールが開いていない限り、ログに記録されたオブジェクトで呼び出されないという事実を利用しています。

var devtools = /./;
devtools.toString = function() {
  if (!this.opened) {
    alert("Opened");
  }
  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からこのソリューションを指摘してくれたPaul Irishに感謝します。

function isInspectOpen() {
  console.profile();
  console.profileEnd();
  if (console.clear) {
    console.clear();
  }
  return console.profiles.length > 0;
}
function showIfInspectIsOpen() {
  alert(isInspectOpen());
}
<button onClick="showIfInspectIsOpen()">Is it open?</button>

window.innerHeight(2011)

この他のオプションは、ページの読み込み後に、ドッキングされているインスペクターが開かれていることを検出できますが、ドッキングされていないインスペクターを検出することはできません。誤検知の可能性もあります。

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


1
TypeErrorの取得:isInspectOpen()でundefinedのプロパティ 'length'を読み取れません
sandeep

2
あります新しい(:@zswangクレジット):新しい最良の方法はstackoverflow.com/questions/7798748/...
ヴィッキーChijwani

3
「toString(2017)」の解決策はChromeでは機能しません
Richard Chan

2
toStringはChromeで修正されたようです。編集。実際function() {}には、正規表現の代わりにを使用すると機能します
Overcl9ck

1
@ Overcl9ckあなたのソリューションは最新のChrome 77アップデートまで機能していました。回避策として正しい方向に向けてください。
アグスティンハラー

118

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


「Element」を印刷すると、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
すばらしい答えです。追加することの1つ... MDN __defineGetter__は非推奨であるため、私はObject.defineProperty(element, 'id', {get:function() {checkStatus='on';}});...まだ機能しているように変更しました。
denikov 2016年

5
また、コンソールはコンソールが開いたらすぐに要素を「読み取る」ので、一度設定して、ゲッター内の関数が実行されるのを待つだけでよいsetInterval
xpy

8
この発見に基づいて、それほど煩わしくない方法を見つけることができました。DevToolsは、関数をコンソールに出力するときに、関数に対してtoString()を呼び出します。したがって、toString()メソッドをオーバーライドしてカスタム関数オブジェクトを出力し、空の文字列を返すことができます。さらに、コンソールのフォーマット文字列%cを使用してcolor:transparentを設定し、印刷される可能性のあるテキストが非表示として印刷されるようにすることができます。私はここで、この手法を使用:github.com/binaryage/cljs-devtools/blob/...
アントニン・ヒルデブラント

3
ここで2017年。Chromeは、ユーザーが開かなくてもコンソールに書き込みを行います。そして、あなたのハックはもう機能しません。
vothaison 2017

2
firefoxでテストすると、Firebugを使用した検査要素(Q)および検査要素では機能しません
Asif Ashraf

27

非常に信頼できるハック

基本的に、プロパティにゲッターを設定し、コンソールにログインします。どうやら事物はコンソールが開いているときにのみアクセスされます。

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').className  = checkStatus;
  requestAnimationFrame(check);
});
.on{
  color:limegreen;
}

.off{
  color:red;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/all.css" integrity="sha256-DVK12s61Wqwmj3XI0zZ9MFFmnNH8puF/eRHTB4ftKwk=" crossorigin="anonymous" />

<p>
  <ul>
    <li>
      dev toolbar open: icon is <span class="on">green</span>
    </li>
    <li>
      dev toolbar closed: icon is <span class="off">red</span>
    </li>
  </ul>
</p>
<div id="devtool-status"><i class="fas fa-7x fa-power-off"></i></div>
<br/>
<p><b>Now press F12 to see if this works for your browser!</b></p>


Chromeバージョン79✅
伝説の

4
何のthrow new Error("Dev tools checker");ため?それがなくても機能するからです。
Legends

これはコンソールをスパムしているようです(開いているとき)?数日後にかなりの量のメモリを消費し始めると思います:)
pythonator

24

DevToolsが開いていることを検出するdevtools-detectを作成しました。

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で動作します。


@barbushin開いている開発ツールがドッキングされていると思います。別のウィンドウを検出できません。
ミスリル2016

15

Chromeコンソールが開いているかどうかを確認する方法を見つけました。それはまだハックですが、より正確であり、コンソールがドッキングされていない場合でも動作します。

基本的に、コンソールを閉じた状態でこのコードを実行すると、約100マイクロ秒かかり、コンソールが開いている間は、約200マイクロ秒かかります。

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

(1ミリ秒= 1000マイクロ秒)

私はそれについてもっとここに書きまし

デモはこちらです。


更新:

@zswangが現在の最善の解決策を見つけました-彼の答えをチェックしてください


1
それは非常に間違った解決策です。Google it-> "Race Hazard"。遅いまたは速いコンピューターと...?
18C

1
「レースハザード」はここでは関係ありません。コンソールを開くと、常に比較的低速になります。
ガイア

1
相対的に遅いが、常に100または200ミリ秒ではない。したがって、レースハザード。ところで 同時にゲームをプレイする場合、この「解決策」は偽陽性の結果を返します。
18C

8

あなたの目標が開発者ツールを妨害することである場合は、これを試してください(JSコードが難読化された場所でそれのより複雑なバージョンを見つけました、それは非常に迷惑です):

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

ユーザーは、Chromeでデバッガーのリッスンを無効にすることができます。
ジャックギフィン2018

3

「タブ」権限のある拡張機能をチェックするためのトリッキーな方法があります:

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

私はこれについてブログ投稿を書きました: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 ?")
    }
  });
});

3
これはすばらしいことですが、ページが古くなり、ユーザーが再開ボタンをクリックするまでメッセージは表示されません。それはユーザーにとって非常に邪魔になります。
ガイア2015年

2
次の「レースハザード」ソリューション。大きな過ち。ところで。「デバッガ」コマンドを無効にすることができます。
18C

3
var div = document.createElement('div');
Object.defineProperty(div,'id',{get:function(){
    document.title = 'xxxxxx'
}});

setTimeout(()=>console.log(div),3000)

うまくいきませんでした。へのリンクが機能test onlineしませんでした。
Samuel

2

Chrome開発者ツールは、実際にはWebKitのWebCoreライブラリの一部にすぎません。したがって、この質問はSafari、Chrome、およびその他のWebCoreコンシューマーに適用されます。

ソリューションが存在する場合、WebKit Webインスペクターが開いているときと閉じているときのDOMの違いに基づいています。残念ながら、これは鶏と卵の問題の一種です。インスペクターが閉じていると、インスペクターを使用してDOMを監視することができないためです。

あなたができるかもしれないことは、DOMツリー全体をダンプするために少しJavaScriptを書くことです。次に、インスペクタが開いているときに1回、閉じているときに1回実行します。DOMの違いはおそらくWebインスペクターの副作用であり、ユーザーが検査しているかどうかをテストするために使用できる可能性があります。

このリンクはDOMダンプスクリプトの良い出発点ですが、DOMWindowだけでなく、オブジェクト全体をダンプする必要がありますdocument

更新:

今これを行う方法があるように見えます。Chrome Inspector Detectorを確認する


Chrome Inspector Detectorは、開発者が述べたようにGoogle Chromeで機能しなくなりました
Angelo

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

1
うまくいきません。ユーザーがモバイルデバイスを使用している場合、デバイスを90度回転すると、画面のサイズが変更されます。
ジャックギフィン2018

クロームで動作し、FFまたはIEではない、または
2019

0

あなたが開発中に何かをしている開発者なら。この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
    }
});

0

ここでいくつかの回答は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);

});

0

クローム/ 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>


0

Muhammad Umerのアプローチがうまくいき、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を使用するすべての人に役立つと思います。誰かがこれを拡張したい場合は、ある時点で無限ループを停止して(すべてのコンポーネントでこれを使用しないため)、コンソールをクリーンに保つ方法を見つけたいと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.