紧张为了通过禁止打开掌握台,防止别人进行代码调试。
转载链接:https://segmentfault.com/a/1190000021459140
//禁止F12键盘事宜document.addEventListener('keydown', function(event){return 123 != event.keyCode || (event.returnValue = false)});//禁止右键、选择、复制document.addEventListener(‘'contextmenu'’, function(event){return event.returnValue = false})
破解:还可以利用浏览器菜单中的开拓者工具打开掌握台

浏览宽高变革监测紧张是监测浏览器可视区域的宽高:window.innerWidth / window.innerHeight(滚动条和内容区)和浏览器宽高:window.outerWidth / window.outerHeight(inner的根本上加上工具条的宽高)之间的差值。
由于我们不知道浏览器是否开启了工具条及工具条的宽高,以是我们设置一个阈值如200,如果outer – inner 大于200,我们就认为开启了掌握台。
function resize(){ var threshold = 200; var widthThreshold = window.outerWidth - window.innerWidth > threshold; var heightThreshold = window.outerHeight - window.innerHeight > threshold; if(widthThreshold || heightThreshold){ console.log('掌握台打开了') }}window.addEventListener('resize', resize);resize()
关于检测窗口大小,有人专门针对此写了个库:https://github.com/sindresorh...,感兴趣的可以去看一下。
破解:监测浏览器宽高变革的缺陷是非常明显的,由于这种监测只能针对掌握台内嵌的环境,但是很多浏览器都支持独立窗口式的掌握台。
3、利用掌握台特性改写工具toString对付一些浏览器,如果掌握台输出的是工具,则保留工具的引用,每次打开掌握台的时候,如果工具类型是function、date等(以前还有regexp,现在已失落效),都会重新调用一下工具的toString()方法,将返回结果打印到掌握台上。
经由测试:1)、先声明工具,再重写toString,末了打印工具,那么toString会在开始时多运行一次,以是可以利用一个计数器来判断哪次有效2)、先声明工具,再打印工具,末了重写toString,那么如果初始化时掌握台是开启状态,会检测不到这一次的状态3)、先声明工具,再重写toString,末了打印工具,但是工具不作为第一个参数,此时就可以成功监测每一次掌握台状态了4)、console.log、console.info、console.error等均有效5)、只在chrome内审阅读器有效,firefox、ie失落效
var devtools = new Date(); //function(){};devtools.toString = function() { console.log('掌握台打开了'); //或实行一段去世循环 window.open("about:blank", "_self"); }console.log('', devtools);
破解:可通过标签注入js代码清空掌握台(添加一个网页标签,标签网址为javascript:console.clear();,进入网页后,点击该标签页,就会运行里面的代码),如果是定时器实行上述代码,还须要重写清空console(javascript:console.clear();for(var k in console){if(typeof console[k] == 'function'){console[k] = function(){}}};)。
4、利用掌握台特性进行监听dom属性大部分浏览器在打印dom元素的时候,如果掌握台处于关闭状态,不会获取元素属性,但是如果掌握台处于开启状态,就会自动获取dom属性,从而触发监听事宜
function observerConsole(){ //这里利用dom元素,在打开掌握台时才司帐算id var dom = document.createElement("div") Object.defineProperty(dom, "id", { get: function(){ console.log('掌握台打开了') } }) //ie不支持console.table //console.info(dom); console.log(dom);}
除了利用console.log,我们还可以利用console.info,console.dir和console.error等等,须要把稳的是ie不支持console.table
破解:通过标签注入js代码清空掌握台,如果是定时器实行打印dom的操作,还须要重写清空console。
上述方法须要把稳浏览器对付defineProperty的支持,其余在firefox浏览器失落效,由于firefox浏览器对付工具中监听的属性不会取值,须要手动点开才会触发。以是对付firefox须要另辟蹊跷才行,这里我选择利用debugger语句来实现,debugger 语句调用任何可用的调试功能,可以阻断代码实行,如果没有调试功能可用,则此语句不起浸染。以是我们可以在debugger前记录韶光,如果debugger没有触发,运行几条语句的韶光险些为0,但是如果被触发,那间隔韶光就不是几十、几百毫秒了。
function observerConsole(){ var obj = Object.create(null), t = Date.now(); Object.defineProperty(obj, "a", { get: function() { if(Date.now() - t > 100){ console.log('掌握台打开了') } } }) setInterval(function(){ t = Date.now(); (function(){})["constructor"]("debugger")();//debugger; console.log(obj.a); }, 200)}
缺陷:如果浏览器取消了debugger调式,那么就毫无意义了。chrome:
Firefox:
汇总3、4,可以做如下封装:
var observerConsole = { openCallback: function(){ console.log('掌握台打开了'); try { window.open("about:blank", "_self") } catch(e) { var btn = document.createElement("button"); btn.onclick = function() { window.open("about:blank", "_self") } btn.click() } }, observer: function(){ //这里利用dom元素,在打开掌握台时才司帐算id var dom = document.createElement("div"), that = this; Object.defineProperty(dom, "id", { get: function(){ that.openCallback() } }) //ie不支持console.table //console.info(dom); console.log(dom); }, observerF: function(){ var obj = Object.create(null), t = Date.now(), that = this; Object.defineProperty(obj, "a", { get: function() { if(Date.now() - t > 100){ that.openCallback() } } }) setInterval(function(){ t = Date.now(); (function(){})["constructor"]("debugger")();//debugger; console.log(obj.a); }, 200) }, init: function(){ var t = window.navigator.userAgent.toLowerCase(); t.indexOf("firefox") >= 0 ? this.observerF() : this.observer(); }}ConsoleManager.init()
破解:通过标签注入js代码清空掌握台、取消console.log等反破解:对console.log等进行重写再包装,如
let _console = { log : console.log, info : console.info, warn : console.warn, error : console.error};
然后利用_console.log等更换上面的console.log。这里可以利用闭包,防止别人对_console的再重写。
代码测试仅测试了firefox、ie、chrome浏览器及部分chrome内审阅读器(如360、qq浏览器、UC浏览器、搜狗浏览器)
5、利用debugger的特性,无限递归这个方法不能监测掌握台被打开,但是能达到不让别人浏览你代码的目的。
上面也说了:debugger 语句调用任何可用的调试功能,可以阻断代码实行,如果没有调试功能可用,则此语句不起浸染。
其余:每个浏览器都有其最大调用栈,如果超出就会抛出Maximum call stack size exceeded的缺点并终止程序。
利用上面讲的特性组合成下面的代码:
function check() { function doCheck(a) { (function() {}["constructor"]("debugger")()); //debugger doCheck(++a); } try { doCheck(0) } catch(err) { console.log(err) }};
上面代码check运行时,如果掌握台未开启,debugger 不会起浸染,但是doCheck会不断循环,直至爆栈,抛出错误,中止本次check运行;如果掌握台开启,则会不断的进行断点调试和循环doCheck的调用,直至爆栈;如果掌握台开启,但是取消了debugger调式,虽然此时debugger 不会起浸染,但递归是依然存在的,而且此时网页性能与未开启掌握台比较会大幅度低落,严重的话,可能会卡去世浏览器。
未开启掌握台时期码运行韶光:Chrome:30-50msFirefox:200-400msIe:10-30ms开启掌握台但取消debugger时期码运行韶光:Chrome:1000-2000msFirefox:页面直接卡去世
从上面的测试结果来看,我们可以设置一个间隔2000ms的定时器来不断实行check,这样当掌握台开启时,不论是否取消debugger调式,都会使页面卡住。其余我们还可以对代码进行稠浊,增加阅读困难度,我们还可以利用闭包完成上面操作,防止别人在掌握台重置check:check=function(){}。
!function(){ var _0x1cbb = ["tor", "struc", "call", "ger", "con", "bug", "de", "apply"]; setInterval(check, 2e3); function check() { function doCheck(_0x1834ff) { if (('' + _0x1834ff / _0x1834ff)['length'] !== 0x1 || _0x1834ff % 0x14 === 0x0) { (function() {return !![]}[ _0x1cbb[0x4] + _0x1cbb[0x1] + _0x1cbb[0x0] ]( _0x1cbb[0x6] + _0x1cbb[0x5] + _0x1cbb[0x3] )[_0x1cbb[0x2]]()); } else { (function() {return ![]}[ _0x1cbb[0x4] + _0x1cbb[0x1] + _0x1cbb[0x0] ]( _0x1cbb[0x6] + _0x1cbb[0x5] + _0x1cbb[0x3] )[_0x1cbb[0x7]]()); } doCheck(++_0x1834ff); } try { doCheck(0) } catch(err) { } };}();
优点:兼容性比较好,不易破解
缺陷:会影响浏览器性能,造成页面卡顿
破解:想办法重置check函数
6、总结如果文章和条记能带您一丝帮助或者启示,请不要吝啬你的赞和收藏,你切实其实定是我提高的最大动力
转载链接:https://segmentfault.com/a/1190000021459140