浏览器开发者工具打开检测

目录

方法一console.log

在safari中,如果打开了控制台,console.log打印日期实例、函数实例、正则实例会触发两次toString方法,那么可以重写toString方法检测是否打开了控制台。

let count = 0;
const temp = () => {}
temp.toString = () => {
  count++;
  return "";
}
console.log(temp);
alert(count)
if (count >= 2) {
  alert('打开了开发中工具');
}

在safari中,如果打开了控制台,console.logdom节点的时候会触发dom节点上id的getter方法,通过自定义这个getter方法来检测是否打开了safari的控制台。

const ele = document.createElement("a");
Object.defineProperty(ele, "id", {
  get: () => {
    alert('打开了开发中工具')
  },
});
console.log(ele)

在Firefox中,如果打开了控制台,console.log正则时候会触发正则的toString方法,那么可以重写toString方法来检测是否打开了控制台。(适用于火狐浏览器, 不适用于chrome safari edge)


const temp = /\./
temp.toString = () => {
  alert('打开了开发中工具');
  return "";
}
console.log(temp);

方法二: debugger

debugger只有在打开控制台的情况下才会触发,而人的手动跳过断点又没有那么快,这中间就有了个时间差,依据这个时间差来判断是否打开了控制台

function detectDebug() {
  const date = Date.now();
  debugger;
  // 你的手不可能快于0.1秒
  if (Date.now() - date > 100) {
    alert('打开了控制台')
  }
}
detectDebug()

方法三:console.table

控制台打开的情况下,console.table的参数如果是一个大对象数组,会比较耗时,而console.log耗时和console.table的耗时差了个量级,通过对比两者的耗时来确定是否打开了控制台。

通过测试总结,如果console.table的耗时超过 console.log的十倍可以确定打开了控制台。

// 创建一个大的数组对象
function createArr() {
  const obj = {};
  for (let i = 0; i < 200; i++) {
    obj[i] = i;
  }
  const arr = [];

  for (let i = 0; i < 100; i++) {
    arr.push(obj);
  }

  return arr;
}

let arr = createArr();

function calculateTime(func) {
  const start = Date.now();
  func();
  return Date.now() - start;
}
// 时间耗时
const tableConsumeTime = calculateTime(() => console.table(arr));

const logConsumeTime = calculateTime(() => console.log(arr));

console.clear()
alert('logPrintTime:' + logConsumeTime)
alert('tablePrintTime:' + tableConsumeTime)

if (tableConsumeTime > logConsumeTime * 10) {
  alert('打开了控制台')
}

方法四:内容宽度

当控制台打开状态下,页面的展示内容是被侵占的,所以可以使用window.outerWidth - window.innerWidth 宽度差来确定是否打开了控制台

有一些情况需要考虑:

  1. 页面缩放会影响window.innerWidth
  2. iframe的window.innerWidth是自己的宽度,而不是顶层页面的宽度
  3. 360浏览器等会有一个边栏放置一些功能菜单,这时候就要将这个差值考虑在内。
  4. 新版chrome浏览器的收藏夹和阅读清单可以在右侧打开一个菜单栏,这个菜单栏也会占用内容区域。
function check(){
  let screenRatio = window.devicePixelRatio

  if(!screenRatio && window.screen.deviceXDPI && window.screen.logicalXDPI ){
    screenRatio = window.screen.deviceXDPI / window.screen.logicalXDPI  
  }

  const widthFlag = window.outerWidth - window.innerWidth * screenRatio > 200;  
  const heightFlag = window.outerHeight - window.innerHeight * screenRatio > 300;  
  if (widthFlag || heightFlag) {
    alert('打开了控制台')
  }
}
check()
window.addEventListener('resize', () => {
  setTimeout(() => {
    check();
  }, 1000);
}, true);

总结

  1. 优先使用方法一,可以在safari firefox中起作用
  2. chrome中使用方法二
  3. 如果禁用了debugger,可以使用方法三,不过方法三属于经验总结,并不一定准确,可能会误判。
  4. 方法四误判的概率更大,如果可以确定目标浏览器,则可以针对性的使用。
posted @ 2023-09-25 13:18  空山与新雨  阅读(611)  评论(0编辑  收藏  举报