JavaScript如何检测或禁止DevTools打开 拦截浏览器菜单唤起路径
先给你泼个冷水
没有任何前端JS方案能100%彻底封死DevTools访问,你之前拦快捷键、拦右键、拦F12,本质上都是防完全不懂技术的普通玩家,但凡会点浏览器操作的,点浏览器右上角菜单找开发者工具、或者直接开独立调试窗口附加到你这个页面,你之前的拦截代码全没用。
而且说句实在的,你把密室逃脱的核心信息存在sessionStorage里本身就属于架构设计问题——前端存储对用户来说是完全透明的,只要能看到就能随便改,你就算把DevTools全封了,用户还能直接在地址栏跑JS读sessionStorage,或者抓包看数据,根本防不住。真要防作弊,核心的通关判定、关键线索校验全放服务端,前端只做画面渲染和操作上报,别把任何不能让玩家看到的东西存在用户本地。
能覆盖菜单打开DevTools场景的检测方案
下面这些方案不需要拦按键,只要DevTools处于打开状态就能检测到,不管你是快捷键开的还是点菜单开的:
- debugger 耗时检测
DevTools挂载的时候,debugger语句的执行耗时会和正常状态有非常明显的差——正常状态下debugger语句不会被断下,执行时间不到1ms,只要DevTools开着,哪怕你关了断点,debugger触发时的执行开销也会涨一大截,定时跑检测逻辑就能抓到。
这个方案对先开DevTools再进页面的场景也生效,唯一的问题是如果用户手动在DevTools里把debugger全禁用了会漏,所以要配合下一个方案一起用。setInterval(() => { const start = performance.now(); debugger; const timeCost = performance.now() - start; if (timeCost > 80) { // 阈值可以自己根据测试调,一般设50-100ms足够 // 检测到之后直接执行惩罚逻辑,别弹个提示就完事 sessionStorage.clear(); document.body.innerHTML = '<div style="text-align:center;margin-top:20vh;font-size:24px">检测到调试行为,游戏进度已重置</div>'; } }, 1200); - Console 懒解析检测
DevTools的console打印引用类型对象的时候是懒解析的——你不开控制台,打印的对象根本不会被读取,只要一打开控制台,控制台要渲染打印内容,就会去读对象的属性,利用这个特性做检测几乎没有误判,不管DevTools是贴在侧边、底部还是开独立窗口都能抓到。const checkTrigger = new Image(); Object.defineProperty(checkTrigger, 'src', { get() { // 触发惩罚 sessionStorage.clear(); location.reload(); } }); setInterval(() => { console.log(checkTrigger); console.clear(); // 定时清控制台,别把打印堆得满屏都是 }, 600); - 窗口尺寸差辅助检测
DevTools停靠在页面内的时候,window.outerWidth - window.innerWidth、window.outerHeight - window.innerHeight的差值会比正常状态大很多(正常状态下这个差值就是浏览器边框的宽度,一般也就十几像素),如果差值突然超过200px,大概率是DevTools打开了,这个方案可以作为前两个的补充,误判率有点高,别单独用。
额外的防护建议
- 核心JS代码记得做混淆压缩,把语义化的变量名全改成乱码,关键逻辑分支加扁平和控制流平坦化,提高用户读代码改逻辑的成本。
- 别在前端存任何核心数据,通关密码、线索有效性判定这类逻辑全扔服务端,前端就算把本地数据改出花来,服务端不认就过不了关,这才是根本的解决方案。
- 检测到调试行为之后别搞什么弹提示警告,直接清存储、重置进度、甚至临时封个几分钟访问,作弊成本高了普通玩家自然不会瞎折腾。
内容的提问来源于stack exchange,提问作者b.cobalt
相关产品推荐
相关产品推荐

