Cari tahu apakah konsol Chrome terbuka

152

Saya menggunakan skrip kecil ini untuk mengetahui apakah Firebug terbuka:

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

Dan itu bekerja dengan baik. Sekarang saya sedang mencari selama setengah jam untuk menemukan cara untuk mendeteksi apakah konsol pengembang web bawaan Google Chrome terbuka, tetapi saya tidak dapat menemukan petunjuk apa pun.

Ini:

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

tidak bekerja.

EDIT:

Jadi tampaknya tidak mungkin untuk mendeteksi apakah konsol Chrome terbuka. Namun ada " peretasan " yang berhasil, dengan beberapa kekurangan:

  • tidak akan berfungsi saat konsol dilepas
  • tidak akan berfungsi saat konsol terbuka saat pemuatan halaman

Jadi, saya akan memilih jawaban Unsigned untuk saat ini, tetapi jika seseorang memiliki ide cemerlang, dia dipersilakan untuk tetap menjawab dan saya mengubah jawaban yang dipilih! Terima kasih!

r0skar.dll
sumber
Solusi dalam jawaban tampaknya berfungsi, namun hanya jika konsol dipasang. Juga tidak berfungsi jika konsol sudah terbuka saat pemuatan halaman, sementara skrip Firebug tidak memiliki masalah ini dan tampaknya selalu berfungsi. Tapi saya bisa hidup dengan itu untuk saat ini! Terima kasih banyak @pimvdb !! Saya akan membiarkan pertanyaan tetap terbuka untuk mungkin menemukan cara yang mirip dengan skrip Firebug, yang selalu berfungsi.
r0skar
Saya telah mencoba hal-hal seperti melakukan kesalahan dan melihat apakah .messagesudah diambil (yang terjadi saat debugger terbuka karena Anda melihat pesannya), tetapi sayangnya ini juga terjadi saat debugger tidak dibuka. Saya ingin tahu
retasan
4
@Spudley Tidak relevan dengan pertanyaan mengapa saya membutuhkannya dan saya tidak ingin mulai menjelaskan. Saya tahu tidak ada cara untuk mencegah some1 dari debugging, tapi bukan itu yang saya coba lakukan. Saya hanya mencoba mencari cara untuk mengetahui apakah konsol terbuka atau tidak. Itu saja :)
r0skar
1
Metode konsol.profil JFYI
loislo

Jawaban:

106

requestAnimationFrame (Akhir 2019)

Meninggalkan jawaban-jawaban sebelumnya di sini untuk konteks sejarah. Saat ini pendekatan Muhammad Umer bekerja di Chrome 78, dengan keuntungan tambahan mendeteksi peristiwa tutup dan terbuka.

function toString (2019)

Penghargaan untuk komentar Overcl9ck atas jawaban ini. Mengganti regex /./dengan objek fungsi kosong masih berfungsi.

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

regex toString (2017-2018)

Karena penanya asli sepertinya tidak ada lagi dan ini masih merupakan jawaban yang diterima, menambahkan solusi ini untuk visibilitas. Kredit pergi ke Antonin Hildebrand 's komentar pada zswang ' s jawaban . Solusi ini memanfaatkan fakta yang toString()tidak dipanggil pada objek yang dicatat kecuali jika konsol terbuka.

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)

Pembaruan: console.profiles telah dihapus dari Chrome. Solusi ini tidak lagi berfungsi.

Terima kasih kepada Paul Irish yang menunjukkan solusi ini dari Discover DevTools , menggunakan profiler:

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)

Opsi lain ini dapat mendeteksi inspektur yang dipasang ke dok sedang dibuka, setelah halaman dimuat, tetapi tidak akan dapat mendeteksi inspektur yang tidak terpasang, atau jika inspektur sudah terbuka saat pemuatan halaman. Ada juga beberapa potensi positif palsu.

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

Tidak ditandatangani
sumber
1
Mendapatkan TypeError: Tidak dapat membaca 'panjang' properti yang tidak ditentukan di isInspectOpen ()
sandeep
2
Ada cara baru terbaik (kredit: @zswang): stackoverflow.com/questions/7798748/…
Vicky Chijwani
3
solusi dari 'toString (2017)' tidak berfungsi di chrome
Richard Chan
2
toString tampaknya telah diperbaiki di chrome. Edit. Sebenarnya ini berfungsi jika Anda menggunakan function() {}alih - alih regex
Overcl9ck
1
@ Overcl9ck solusi Anda berfungsi hingga pembaruan Chrome 77 terbaru. Bisakah Anda mengarahkan kami ke arah yang benar untuk mendapatkan solusi?
Agustin Haller
119

Chrome 65+ (2018)

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

demo: https://jsbin.com/cecuzeb/edit?output (Perbarui pada 2018-03-16)

paket: https://github.com/zswang/jdetects


Saat mencetak "Elemen", alat pengembang Chrome akan mendapatkan id-nya

var checkStatus;

var element = document.createElement('any');
element.__defineGetter__('id', function() {
    checkStatus = 'on';
});

setInterval(function() {
    checkStatus = 'off';
    console.log(element);
    console.clear();
}, 1000);

Versi lain (dari komentar)

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

Cetak variabel biasa :

var r = /./;
r.toString = function() {
  document.title = 'on';
};
console.log(r);
zswang
sumber
3
Jawaban yang bagus. Satu hal untuk ditambahkan ... MDN mengatakan __defineGetter__sudah usang jadi saya berubah menjadi Object.defineProperty(element, 'id', {get:function() {checkStatus='on';}});... masih bekerja.
denikov
5
Juga konsol akan 'membaca' elemen segera setelah konsol terbuka, jadi Anda bisa mencetak sekali dan hanya menunggu fungsi di getter untuk dijalankan alih-alih mengatursetInterval
xpy
8
Berdasarkan penemuan ini saya dapat menemukan metode yang tidak terlalu mengganggu. DevTools memanggil toString () pada fungsi saat mencetaknya ke konsol. Jadi seseorang bisa mencetak objek fungsi kustom dengan metode toString () menimpa mengembalikan string kosong. Selain itu, Anda dapat menggunakan string pemformatan konsol% c dan mengatur color: transparent untuk memastikan teks yang mungkin dicetak tidak terlihat. Saya menggunakan teknik ini di sini: github.com/binaryage/cljs-devtools/blob/…
Antonin Hildebrand
3
Tahun 2017 di sini. Chrome masih menulis sesuatu ke konsol tanpa Anda membukanya. Dan retasan Anda tidak berfungsi lagi.
vothaison
2
Diuji pada firefox tidak bekerja dengan Elemen Inspeksi (Q) dan Elemen Inspeksi dengan firebug
Asif Ashraf
37

Retas yang sangat andal

Pada dasarnya mengatur getter pada properti dan mencatatnya di konsol. Rupanya hal itu hanya dapat diakses ketika konsol terbuka.

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>

Muhammad Umer
sumber
Chrome versi 79 ✅
Legends
5
Untuk apa throw new Error("Dev tools checker");? Karena ia bekerja tanpa itu.
Legenda
1
ini tampaknya spam konsol (saat terbuka)? yang saya asumsikan akan mulai memakan sejumlah besar memori setelah beberapa hari :)
pythonator
1
Berbakat! Metode ini dapat diubah dengan sesuatu seperti console.log = function() {}dan console.dir = function() {}.
Nathan Goings
Apakah mungkin untuk mengalihkan halaman jika Elemen Inspeksi Terbuka. Tolong beritahu jika Mungkin. Terima Kasih
Himanshu Jain
24

Saya membuat devtools-detect yang mendeteksi saat DevTools terbuka:

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

Anda juga dapat mendengarkan acara:

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

Ini tidak berfungsi saat DevTools dilepas. Namun, bekerja dengan Chrome / Safari / Firefox DevTools dan Firebug.

Sindre Sorhus
sumber
@barbushin Saya pikir devtool terbuka Anda berlabuh, tidak dapat mendeteksi jendela terpisah.
Mithril
Sayangnya itu berhenti bekerja untuk Chrome github.com/sindresorhus/devtools-detect/issues/40
laike9m
15

Saya menemukan cara untuk mengetahui apakah Konsol Chrome dibuka atau tidak. Ini masih merupakan peretasan tetapi jauh lebih akurat dan akan berfungsi jika konsol tidak terkunci atau tidak.

Pada dasarnya menjalankan kode ini dengan konsol tertutup membutuhkan waktu sekitar ~ 100 mikrodetik dan saat konsol dibuka, dibutuhkan sekitar dua kali lipat ~ 200 mikrodetik.

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

(1 milidetik = 1000 mikrodetik)

Saya telah menulis lebih banyak tentang itu di sini .

Demo ada di sini .


Memperbarui:

@zswang telah menemukan solusi terbaik saat ini - lihat jawabannya

guya
sumber
1
Ini adalah solusi yang sangat salah. Google it -> "Race Hazard". Komputer lebih lambat atau lebih cepat dan ...?
18C
1
"Race Hazard" tidak berhubungan di sini. Selalu ada kelambatan relatif saat konsol dibuka.
guya
1
Kelambatan relatif tetapi tidak selalu 100 atau 200ms. Jadi Race Hazard. Btw. Jika Anda akan bermain game dalam waktu yang sama, "solusi" ini akan mengembalikan hasil positif palsu.
18C
8

Jika tujuan Anda adalah untuk mengacaukan alat pengembang, coba ini (saya menemukan versi yang lebih rumit di tempat kode JS dikaburkan, itu sangat mengganggu):

setTimeout(function() {while (true) {eval("debugger");}}, 0);
Robert Moore
sumber
Pengguna dapat, di Chrome, menonaktifkan mendengarkan debugger.
Jack Giffin
@JackGiffin, Sampai saat ini ada masalah aneh di Chrome Deactivating breakpoints tidak berfungsi 100%. Sudah diperbaiki sekarang, tetapi pada saat posting ini berfungsi.
Nathan Goings
4

Saya menulis entri blog tentang ini: http://nepjua.org/check-if-browser-console-is-open/

Itu dapat mendeteksi apakah itu berlabuh atau tidak

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 ?")
    }
  });
});
nepjua
sumber
3
Itu bagus, tapi, halaman itu akan basi dan tidak ada pesan yang akan ditampilkan sampai pengguna mengklik tombol resume. Ini akan sangat mengganggu pengguna.
guya
3
Solusi "Race Hazard" berikutnya. Sangat salah. BTW. Perintah "debugger" dapat dinonaktifkan.
18C
3

Ada cara yang rumit untuk memeriksanya untuk ekstensi dengan izin 'tab':

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

Anda juga dapat memeriksa apakah itu terbuka untuk halaman Anda:

chrome.tabs.query({
    url: 'chrome-devtools://*/*',
    title: '*example.com/your/page*'
}, function(tabs){ ... })
norlin
sumber
3
var div = document.createElement('div');
Object.defineProperty(div,'id',{get:function(){
    document.title = 'xxxxxx'
}});

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

huiting Chen
sumber
Tidak berhasil. Dan tautan ke test onlinetidak berfungsi.
Samuel
2

Alat pengembang Chrome sebenarnya hanyalah bagian dari pustaka WebCore WebKit. Jadi pertanyaan ini berlaku untuk Safari, Chrome, dan konsumen WebCore lainnya.

Jika ada solusi, itu akan didasarkan pada perbedaan di DOM saat pemeriksa web WebKit terbuka dan tertutup. Sayangnya, ini adalah masalah ayam dan telur karena kita tidak dapat menggunakan inspektur untuk mengamati DOM saat inspektur ditutup.

Apa yang mungkin dapat Anda lakukan adalah menulis sedikit JavaScript untuk membuang seluruh pohon DOM. Kemudian jalankan sekali saat inspektur terbuka, dan sekali saat inspektur ditutup. Perbedaan apa pun di DOM mungkin merupakan efek samping dari pemeriksa web, dan kami mungkin dapat menggunakannya untuk menguji apakah pengguna sedang memeriksa atau tidak.

Tautan ini adalah awal yang baik untuk skrip dumping DOM, tetapi Anda ingin membuang seluruh DOMWindowobjek, tidak hanya document.

Memperbarui:

Sepertinya ada cara untuk melakukannya sekarang. Lihat Detektor Inspektur Chrome

pepsi
sumber
Detektor Inspektur Chrome tidak lagi berfungsi untuk google chrome seperti yang disebutkan oleh pengembang
Angelo
1

Anda juga dapat mencoba ini: 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);
});
vovchisko
sumber
1
Tidak bekerja dengan baik. Jika pengguna menggunakan perangkat seluler, kemudian mereka memutar perangkat 90 derajat, maka ukuran layar akan berubah.
Jack Giffin
bekerja pada chrome dan ff bukan ie atau edge pada 4/5/2019
SolidSnake
1

Pendekatan Muhammad Umer berhasil untuk saya, dan saya menggunakan React, jadi saya memutuskan untuk membuat solusi hook:

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
}

CATATAN: Ketika saya mengotak-atiknya, itu tidak berfungsi untuk waktu yang lama dan saya tidak tahu mengapa. Saya telah menghapus console.dir(element);yang sangat penting untuk cara kerjanya. Saya menghapus sebagian besar tindakan konsol non-deskriptif karena mereka hanya mengambil ruang dan biasanya tidak diperlukan untuk fungsi tersebut, jadi itulah mengapa itu tidak berfungsi untuk saya.

Untuk menggunakannya:

import React from 'react'

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

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

Saya harap ini membantu siapa pun yang menggunakan React. Jika ada yang ingin mengembangkan ini, saya ingin dapat menghentikan loop tak terbatas di beberapa titik (karena saya tidak menggunakan ini di setiap komponen) dan menemukan cara untuk menjaga konsol tetap bersih.

Luke Redmore
sumber
Apakah mungkin untuk mengalihkan halaman jika Elemen Inspeksi Terbuka. Tolong beritahu jika Mungkin. Terima Kasih
Himanshu Jain
0

Jika Anda adalah pengembang yang melakukan banyak hal selama pengembangan. Lihat ekstensi Chrome ini. Ini membantu Anda mendeteksi kapan Chrome Devtoos dibuka atau ditutup.

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

Ekstensi ini membantu pengembang Javascript mendeteksi saat Chrome Devtools dibuka atau ditutup pada halaman saat ini. Saat Chrome Devtools menutup / membuka, ekstensi akan memunculkan peristiwa bernama 'devtoolsStatusChanged' pada elemen window.document.

Ini adalah contoh kode:

 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
    }
});
vothaison
sumber
0

Beberapa jawaban di sini akan berhenti berfungsi di Chrome 65. Berikut adalah alternatif serangan waktu yang bekerja cukup andal di Chrome, dan jauh lebih sulit untuk dimitigasi daripada toString()metode. Sayangnya itu tidak dapat diandalkan di 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);

});
Eli Grey
sumber
0

Adapun Chrome / 77.0.3865.75 versi 2019 tidak berfungsi. toString segera dipanggil tanpa pembukaan Inspektur.

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

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

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

korzhyk.dll
sumber
-1

gunakan isDevToolsOpened()fungsi paket ini dari paket dev-tools-monitor yang berfungsi seperti yang diharapkan di semua browser kecuali firefox.

pengguna8251997
sumber