Tìm hiểu xem bảng điều khiển Chrome có mở không


141

Tôi đang sử dụng tập lệnh nhỏ này để tìm hiểu xem Fireorms có mở không:

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

Và nó hoạt động tốt. Bây giờ tôi đã tìm kiếm trong nửa giờ để tìm cách phát hiện xem bảng điều khiển dành cho nhà phát triển web tích hợp của Google Chrome có mở hay không, nhưng tôi không thể tìm thấy bất kỳ gợi ý nào.

Điều này:

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

không hoạt động.

BIÊN TẬP:

Vì vậy, dường như không thể phát hiện liệu bảng điều khiển Chrome có mở hay không. Nhưng có một " hack " hoạt động, với một số nhược điểm:

  • sẽ không hoạt động khi giao diện điều khiển không bị khóa
  • sẽ không hoạt động khi giao diện điều khiển được mở khi tải trang

Vì vậy, bây giờ tôi sẽ chọn câu trả lời của Unsigns, nhưng nếu ai đó nghĩ ra một ý tưởng tuyệt vời, anh ấy vẫn sẵn sàng trả lời và tôi thay đổi câu trả lời đã chọn! Cảm ơn!



Giải pháp trong câu trả lời dường như hoạt động, tuy nhiên chỉ khi bàn điều khiển được gắn. Ngoài ra, nó không hoạt động nếu bảng điều khiển đã mở khi tải trang, trong khi tập lệnh Fireorms không có vấn đề này và dường như luôn hoạt động. Nhưng tôi có thể sống với điều đó ngay bây giờ! Cảm ơn rất nhiều @pimvdb !! Tôi sẽ tiếp tục mở câu hỏi để có thể tìm ra cách tương tự với kịch bản Fireorms, luôn hoạt động.
r0skar

Tôi đã thử những thứ như ném lỗi và xem liệu có .messageđược tải hay không (điều này xảy ra khi trình gỡ lỗi mở vì bạn thấy thông báo), nhưng thật không may, điều này cũng xảy ra khi trình gỡ lỗi không được mở. Tôi muốn biết một hack cho điều này nếu nó tồn tại ...
pimvdb

4
@Spudley Nó không liên quan đến câu hỏi tại sao tôi cần nó và tôi không muốn bắt đầu giải thích. Tôi biết không có cách nào để ngăn ai đó gỡ lỗi, nhưng đó không phải là điều tôi đang cố gắng làm. Tôi chỉ đang cố gắng tìm ra một cách để biết giao diện điều khiển có mở hay không. Đó là tất cả :)
r0skar

1
Phương thức console.profiles của JFYI đã bị xóa khỏi API bảng điều khiển gần đây src.chromium.org/viewvc/blink?view=revision&revision=151136
loislo

Câu trả lời:


97

requestAnimationFrame (Cuối năm 2019)

Để lại những câu trả lời trước đây ở đây cho bối cảnh lịch sử. Hiện tại phương pháp của Muhammad Umer hoạt động trên Chrome 78, với lợi thế bổ sung là phát hiện cả các sự kiện gần và mở.

chức năng toString (2019)

Tín dụng cho nhận xét của Overcl9ck về câu trả lời này. Thay thế regex /./bằng một đối tượng hàm rỗng vẫn hoạt động.

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)

Vì người hỏi ban đầu dường như không còn ở đây nữa và đây vẫn là câu trả lời được chấp nhận, thêm giải pháp này cho khả năng hiển thị. Tín dụng đi đến bình luận của Antonin Hildebrand về câu trả lời của zswang . Giải pháp này lợi dụng thực tế là không được gọi trên các đối tượng đã ghi trừ khi bàn điều khiển được mở.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)

Cập nhật: console.profiles đã bị xóa khỏi Chrome. Giải pháp này không còn hoạt động.

Cảm ơn Paul Irish đã chỉ ra giải pháp này từ Discover DevTools , sử dụng trình lược tả:

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)

Tùy chọn khác này có thể phát hiện trình kiểm tra được neo đang được mở, sau khi tải trang, nhưng sẽ không thể phát hiện trình kiểm tra không bị khóa hoặc nếu trình kiểm tra đã mở khi tải trang. Cũng có một số tiềm năng cho dương tính giả.

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


1
Bắt TypeError: Không thể đọc thuộc tính 'độ dài' của không xác định trong isInspectOpen ()
sandeep

2
Có một cách mới tốt nhất (tín dụng: @zswang): stackoverflow.com/questions/7798748/
Kẻ

3
giải pháp của 'toString (2017)' không hoạt động trong chrome
Richard Chan

2
toString dường như đã được cố định trong chrome. Biên tập. Trên thực tế, nó hoạt động nếu bạn sử dụng function() {}thay vì regex
Overcl9ck

1
@ Overcl9ck giải pháp của bạn đã hoạt động cho đến khi cập nhật Chrome 77 mới nhất. Bạn có thể chỉ cho chúng tôi đi đúng hướng cho một cách giải quyết?
Agustin Haller

118

Chrome 65+ (2018)

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

bản demo: https://jsbin.com/cecuzeb/edit?output (Cập nhật vào 2018-03-16)

gói: https://github.com/zswang/jdetects


Khi in các công cụ dành cho nhà phát triển Chrome Element Chrome Chrome sẽ nhận id

var checkStatus;

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

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

Một phiên bản khác (từ ý kiến)

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

In một biến thường xuyên

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

3
Câu trả lời chính xác. Một điều cần thêm ... MDN nói __defineGetter__là không dùng nữa nên tôi đổi thành Object.defineProperty(element, 'id', {get:function() {checkStatus='on';}});... vẫn hoạt động.
denikov

5
Ngoài ra, bàn điều khiển sẽ 'đọc' phần tử ngay khi bảng điều khiển mở ra, vì vậy bạn có thể chỉ cần in một lần và chỉ cần chờ chức năng trong getter thực thi thay vì đặtsetInterval
xpy

8
Dựa trên khám phá này, tôi đã có thể tìm ra phương pháp ít xâm phạm hơn. DevTools gọi toString () trên các chức năng khi in chúng ra bàn điều khiển. Vì vậy, người ta có thể in một đối tượng hàm tùy chỉnh bằng phương thức toString () ghi đè trả về chuỗi trống. Ngoài ra, bạn có thể sử dụng chuỗi định dạng bảng điều khiển% c và đặt màu: trong suốt để đảm bảo các bản in văn bản có khả năng được in dưới dạng vô hình. Tôi đã sử dụng kỹ thuật này tại đây: github.com/binaryage/cljs-devtools/blob/ mẹo
Antonin Hildebrand

3
Năm 2017 tới đây. Chrome vẫn ghi mọi thứ vào bảng điều khiển mà không cần bạn mở nó. Và hack của bạn không hoạt động nữa.
vothaison

2
Đã thử nghiệm trên firefox không hoạt động với Kiểm tra phần tử (Q) và Kiểm tra phần tử với bọ lửa
Asif Ashraf

27

Hack rất đáng tin cậy

Về cơ bản thiết lập một getter trên thuộc tính và đăng nhập nó trong giao diện điều khiển. Rõ ràng điều này chỉ được truy cập khi giao diện điều khiển được mở.

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 phiên bản 79
Huyền thoại

4
Để làm gì throw new Error("Dev tools checker");? Bởi vì nó hoạt động mà không có nó.
Huyền thoại

Điều này xuất hiện để spam bảng điều khiển (khi mở)? mà tôi cho rằng sẽ bắt đầu ăn một lượng bộ nhớ đáng kể sau vài ngày :)
pythonator

24

Tôi đã tạo devtools-phát hiện phát hiện khi DevTools mở:

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

Bạn cũng có thể nghe một sự kiện:

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

Nó không hoạt động khi DevTools không bị khóa. Tuy nhiên, hoạt động với DevTools và Firebird của Chrome / Safari / Firefox.


@barbushin Tôi nghĩ rằng devtool mở của bạn đã cập cảng, nó không thể phát hiện cửa sổ riêng biệt.
Mithril

15

Tôi đã tìm thấy một cách để biết Chrome Console có được mở hay không. Nó vẫn là một bản hack nhưng nó chính xác hơn và sẽ hoạt động tốt hơn khi giao diện điều khiển không bị khóa hay không.

Về cơ bản, việc chạy mã này với giao diện điều khiển đóng mất khoảng ~ 100 micro giây và trong khi giao diện điều khiển được mở, phải mất khoảng gấp đôi ~ 200 micro giây.

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

(1 mili giây = 1000 micro giây)

Tôi đã viết thêm về nó ở đây .

Demo là đây .


Cập nhật:

@zswang đã tìm ra giải pháp tốt nhất hiện tại - hãy xem câu trả lời của anh ấy


1
Đó là giải pháp rất sai. Google nó -> "Nguy hiểm chủng tộc". Máy tính chậm hơn hay nhanh hơn và ...?
18C

1
"Cuộc đua nguy hiểm" không liên quan ở đây. Luôn luôn có một sự chậm chạp tương đối khi giao diện điều khiển được mở.
chàng trai

1
Chậm tương đối nhưng không phải luôn luôn 100 hoặc 200ms. Do đó, nguy hiểm chủng tộc. Btw. Nếu bạn sẽ chơi một trò chơi cùng một lúc, "giải pháp" này sẽ trả về kết quả dương tính giả.
18C

8

Nếu mục tiêu của bạn là gây nhiễu các công cụ dành cho nhà phát triển, hãy thử điều này (tôi đã tìm thấy một phiên bản phức tạp hơn của nó tại một nơi mà mã JS bị xáo trộn, điều đó rất khó chịu):

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

Người dùng có thể, trong Chrome, vô hiệu hóa nghe trình gỡ lỗi.
Jack Giffin

3

Có một cách khó khăn để kiểm tra các tiện ích mở rộng có quyền 'tab':

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

Ngoài ra, bạn có thể kiểm tra nếu nó mở cho trang của bạn:

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

3

Tôi đã viết một bài blog về điều này: http://nepjua.org/check-if-browser-console-is-open/

Nó có thể phát hiện xem nó đã cập cảng hay không khóa

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
Điều đó thật tuyệt, nhưng, nó sẽ cũ trang và sẽ không có thông báo nào được hiển thị cho đến khi người dùng nhấp vào nút tiếp tục. Nó sẽ rất khó chịu cho người dùng.
chàng trai

2
Giải pháp "Cuộc đua nguy hiểm" tiếp theo. Rất sai. BTW. Lệnh "gỡ lỗi" có thể bị vô hiệu hóa.
18C

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

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

Nó không hoạt động. Và liên kết đến test onlinekhông hoạt động.
Samuel

2

Các công cụ dành cho nhà phát triển Chrome thực sự chỉ là một phần của thư viện WebCore của WebKit. Vì vậy, câu hỏi này áp dụng cho Safari, Chrome và bất kỳ người tiêu dùng WebCore nào khác.

Nếu một giải pháp tồn tại, nó sẽ dựa trên sự khác biệt trong DOM khi trình kiểm tra web WebKit mở và khi nó đóng. Thật không may, đây là một vấn đề về gà và trứng vì chúng ta không thể sử dụng thanh tra để quan sát DOM khi đóng thanh tra.

Những gì bạn có thể làm là viết một chút JavaScript để kết xuất toàn bộ cây DOM. Sau đó chạy nó một lần khi thanh tra mở và một lần khi thanh tra đóng cửa. Bất kỳ sự khác biệt nào trong DOM có lẽ là tác dụng phụ của trình kiểm tra web và chúng tôi có thể sử dụng nó để kiểm tra xem người dùng có đang kiểm tra hay không.

Đây liên kết là một khởi đầu tốt cho một DOM bán phá giá kịch bản, nhưng bạn sẽ muốn để đổ toàn bộ DOMWindowđối tượng, không chỉ document.

Cập nhật:

Có vẻ như có một cách để làm điều này bây giờ. Kiểm tra trình phát hiện thanh tra Chrome


Trình phát hiện thanh tra Chrome không còn hoạt động đối với google chrome như được nhà phát triển đề cập
Angelo

1

Ngoài ra, bạn có thể thử điều này: 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
Không hoạt động tốt. Nếu người dùng ở trên thiết bị di động, sau đó họ xoay thiết bị 90 độ, màn hình sẽ thay đổi kích thước.
Jack Giffin

công trình trên chrome và ff không tức hoặc cạnh như của 2019/04/05
SolidSnake

0

Nếu bạn là nhà phát triển đang làm công cụ trong quá trình phát triển. Hãy xem tiện ích mở rộng Chrome này. Nó giúp bạn phát hiện khi Chrome Devtoos được mở hoặc đóng.

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

Tiện ích mở rộng này giúp nhà phát triển Javascript phát hiện khi Chrome Devtools mở hoặc đóng trên trang hiện tại. Khi Chrome Devtools đóng / mở, tiện ích mở rộng sẽ đưa ra một sự kiện có tên 'devtoolsStatusChanged' trên phần tử window.document.

Đây là mã ví dụ:

 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

Một số câu trả lời ở đây sẽ ngừng hoạt động trong Chrome 65. Đây là một giải pháp thay thế tấn công thời gian hoạt động khá đáng tin cậy trong Chrome và khó giảm thiểu hơn nhiều so với toString()phương pháp. Thật không may, nó không đáng tin cậy trong 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

Đối với Chrome / 77.0,3865,75, một phiên bản 2019 không hoạt động. toString gọi ngay lập tức mà không cần mở Thanh tra.

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

Cách tiếp cận của Muhammad Umer làm việc cho tôi và tôi đang sử dụng React, vì vậy tôi quyết định thực hiện một giải pháp 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
}

LƯU Ý: Khi tôi gặp rắc rối với nó, nó không hoạt động trong thời gian dài nhất và tôi không thể hiểu tại sao. Tôi đã xóa console.dir(element);nó rất quan trọng đối với cách nó hoạt động. Tôi xóa hầu hết các hành động bảng điều khiển không mô tả vì chúng chỉ chiếm dung lượng và thường không cần thiết cho chức năng, vì vậy đó là lý do tại sao nó không hoạt động đối với tôi.

Để dùng nó:

import React from 'react'

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

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

Tôi hy vọng điều này sẽ giúp bất cứ ai sử dụng React. Nếu bất cứ ai muốn mở rộng về điều này, tôi muốn có thể dừng vòng lặp vô hạn tại một số điểm (vì tôi không sử dụng điều này trong mọi thành phần) và tìm cách giữ cho bàn điều khiển sạch sẽ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.