
大家好,我来了😁。
前端代码在浏览器里是裸奔的。------这几乎是所有开发者的共识。
只要用户按一下 F12,你的源码、你的接口、你的数据结构,全部一览无余。黑客可以修改你的变量,脚本小子可以刷你的接口,竞品可以分析你的逻辑。
很多老板会问:能不能禁止用户打开控制台?
通常我们的回答是:不能。浏览器是用户的地盘,我们无权干涉。
但是, 禁止不了,不代表我们检测不到。
如果在检测到用户打开 DevTools 的那一瞬间,我们立马清空敏感数据 、停止视频播放 、或者无限 debugger 卡死页面,是不是就能极大地提高攻击者的门槛?🤔
今天,我就来分享几种利用浏览器API技巧实现的 DevTools 检测技术。
1.利用 debugger 的时间差
这是最古老、最暴力,但也最有效的方法之一。
原理:
当 DevTools 打开,并且开启了断点调试功能时,代码执行到 debugger 语句会暂停。
而不打开 DevTools 时,debugger 语句会被浏览器忽略,代码瞬间执行过去。
我们可以记录 debugger 语句前后的时间戳。如果差值过大,说明代码被暂停了------也就是说,DevTools 肯定是开着的。
具体代码👇:
JavaScript
function checkDevTools() {
const start = Date.now();
// 核心:这就好比在路上设个卡
debugger;
const end = Date.now();
// 如果暂停时间超过 100ms,判定为有人在调试
if (end - start > 100) {
console.log("警告:检测到开发者工具已打开!");
// 这里可以执行你的防御逻辑:
// window.location.reload();
// clearSensitiveData();
}
}
// 搞个定时器,每秒查岗一次
setInterval(checkDevTools, 1000);
优点是简单粗暴,对付小白有效。
缺点的话 有点扰民😖。如果攻击者禁用了断点功能(Deactivate breakpoints),或者设置⚙中配置了Never pause here,这招就废了。
2.利用 console.log 的对象懒加载
这是一个非常骚的检测方法,利用了 Chrome 控制台的一个特性:对象求值(Object Evaluation) 。
原理:
当你执行 console.log(obj) 时,浏览器为了性能,并不会立刻把 obj 的所有属性打印出来。它只打印一个引用。
只有当控制台真的是打开状态,并且需要显示内容时,浏览器才会去读取这个对象的属性(getters)。
我们可以给一个对象定义一个 getter(读取器)。如果这个 getter 被触发了,就说明有一个观察者(DevTools)正在看它。
直接上代码👇:
JavaScript
const element = new Image();
Object.defineProperty(element, 'id', {
get: function () {
// 只有当 DevTools 打开时,浏览器尝试获取 element.id 来显示详情
// 这个 getter 才会执行
console.log('抓到你了!DevTools 是开着的!');
// 执行防御逻辑
alert('请关闭开发者工具继续浏览!');
return 'detected';
}
});
// 定时打印这个 element
// 如果控制台没开,log 只是静默执行,不会触发 getter
// 如果控制台开了,log 为了显示 element 的详情,会触发 getter
setInterval(() => {
console.log(element);
console.clear(); // 刷屏清空,防止用户发现
}, 1000);
优点是隐蔽性极强,不需要 debugger,不会打断代码执行。缺点呢?严重依赖浏览器实现。Chrome 上效果最好,Firefox/Safari 的行为可能不同。
3.无限 Debugger (防调试)
这其实不是检测,而是劝退。
很多网站(比如某些视频站、加密小说站),会用一种让黑客极其恶心的手段:只要你敢开控制台,我就让你卡死。
原理:
利用 Function.constructor 或 eval,在一个高频循环里不断生成新的 debugger。
JavaScript
// 放在一个立即执行函数里
(function anonymous() {
// 定义一个生成 debugger 的函数
function debuggerLoop() {
try {
// 通过构造函数生成 debugger,防止源码被静态搜索到
(new Function("debugger"))();
} catch (e) {}
}
// 只要没被拦截,我就一直递归调用
// 也可以配合 setInterval
setInterval(() => {
debuggerLoop();
}, 50); // 每 50ms 炸你一次🤣
})();
效果:

一旦你打开 F12,你的浏览器就会立刻被无数个断点暂停。点击继续运行?没用,50ms 后下一个断点又来了。你的页面基本处于假死状态,根本没法操作 DOM 或发请求。
这也是为什么你在调试某些网站时,会发现 Sources 面板里全是 VMxxxx 开头的匿名脚本,而且一直卡在 debugger 上。
如何绕过呢?🤔
作为补充,我必须告诉你,这些防御都不是无敌的。
对于无限 Debugger:
- 禁用断点:在 Chrome DevTools 里点击那个禁用所有断点的图标,世界瞬间清净了。

- 条件断点 :在那个
debugger行右键 -> 停用断点。

- 本地替换:用 Chrome 的 本地替换功能,把那段 JS 代码替换成本地空文件。

对于Getter 检测呢?🤔
黑客可以直接 Hook console.log,让它失效😖。
JavaScript
// 你的检测逻辑就废了
window.console.log = function() {};
任何前端安全手段,本质上都是 防君子,防不了小人 ,或者说是提高攻击门槛。
在浏览器这个完全开放的环境里,没有什么秘密能真正藏得住。
不要把核心业务逻辑(比如金额计算、权限校验)放在前端。
这些检测手段,更多是用来保护知识产权 (防止小白扒代码)或者反爬虫(检测到调试就停止渲染数据)。
学会这几招,起码能挡住 90% 的脚本小子。
