问题发生背景:
某些网站利用js代码,阻止用户使用F12打开debug调试,通过查看网页源代码,发现以下代码:
//debug调试时跳转页面 var element = new Image(); Object.defineProperty(element,\'id\',{get:function(){window.location.href="http://www.baidu.com"}}); console.log(element);
以上代码创建了一个<img>标签,利用Object.defineProperty方法,在这个img上定义了id的getter,每当打印element时,就会调用这个getter,跳转到百度。
在知乎上也看到过这个阻止debug调试的方法,但没有给出破解方法,最近连续在两个网站中发现这个代码,于是尝试破解
浏览器:chrome
破解过程:
1. 毁掉console.log,从而阻止跳转
在查阅相关解决方法时,找到https://segmentfault.com/q/1010000013487697,其中有一个方法,在书签中添加 javascript:console.log=function(){};,点一下这个书签来运行这段js代码,从而毁掉console.log方法(此前都不知道书签还能用来运行js,长知识了)。然而实际上,浏览器会先执行console.log(element)再执行console.log=function(){},仍然会跳转到百度,此方法失败。
2. 监听beforeunload事件
再次利用书签的方法来运行js:javascript:window.addEventListener(\'beforeunload\', function (e) { e.preventDefault();e.returnValue = \'\' });
通过监听beforeunload事件并指定returnValue,浏览器会在网页跳转前询问是否离开此网页,点击取消即可留在当前页面。这样当我们打开debug调试时,就可以取消页面跳转了。
一些迷惑:
1. console.log的执行时机:
在Chrome中,console.log在控制台打开后才起作用,它的确是调用了,但是还没打印,也就是还没有触发<img>标签id的getter;因此用书签来毁掉console.log是在调用之后的,无法阻止打开debug时打印<img>标签从而触发getter方法。如果我们用书签再次定义element的id的getter呢,结果也是失败,因为对getter的重新定义也是在console.log调用之后发生的。这个console.log就像薛定谔的猫,当你打开debug它才会打印,但它已经发生了,你改变不了它发生的事实,除非在网页加载前就去掉这段代码或毁掉console.log。
2. 刷新页面读取network的数据:
用debug调试读取network发过来的数据,必须要刷新页面,一旦刷新,我们对beforeunload的监听就会失效,必定触发重定向,导致无法获取network中资源的请求和响应数据。这时候单纯使用浏览器的debug调试就很难拿到这些数据了,可以考虑使用postman直接抓包处理。
总结:
js代码无法阻止用户使用debug调试,但是能够增加用户调试的难度,要看你的页面代码始终有办法。
那么有没有仅用浏览器获取network数据的方法呢,能否在页面运行上述代码前毁掉console.log?各位大佬求解!
(这里是前端小白Jiny,甚至还没找到工作)