JS禁止打开控制台

时间: 2019-12-03阅读: 372标签: js技巧

主要为了通过禁止打开控制台,防止别人进行代码调试。

1、禁止右键查看源码和F12

//禁止F12键盘事件
document.addEventListener('keydown', function(event){
   return 123 != event.keyCode || (event.returnValue = false)
});
//禁止右键、选择、复制
document.addEventListener(‘'contextmenu'’, function(event){
   return event.returnValue = false
})

破解:还可以使用浏览器菜单中的开发者工具打开控制台


2、通过页面宽度变化监测控制台

浏览宽高变化监测主要是监测浏览器可视区域的宽高: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调式,那么就毫无意义了。

汇总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-50ms
Firefox:200-400ms
Ie:10-30ms

开启控制台但取消debugger时代码运行时间:
Chrome:1000-2000ms
Firefox:页面直接卡死

从上面的测试结果来看,我们可以设置一个间隔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函数

原文:https://segmentfault.com/a/1190000021459140


站长推荐

1.阿里云: 本站目前使用的是阿里云主机,安全/可靠/稳定。点击领取2000元代金券、了解最新阿里云产品的各种优惠活动点击进入

2.腾讯云: 提供云服务器、云数据库、云存储、视频与CDN、域名等服务。腾讯云各类产品的最新活动,优惠券领取点击进入

3.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/7149

三个实用的javascript小技巧

如果你想从后向前获取一个数组的元素,可以这样写:如果你想在某个条件逻辑值为true时,执行某个函数,就像这样:如果你必须给一个变量赋默认值,可以简单的这样写:

JS技巧技法总结

闭包原理、数组展平、前端语音(在项目中需要对ajax请求返回的消息进行语音播报,str 为返回的data)、Proxy 数据绑定和监听、计数器

javascript如何判断值是否为整数?

javascript如何判断一个值是否为整数?下面本篇文章就来给大家介绍一下使用javascript判断一个值是否为整数的方法。

(a ==1 && a== 2 && a==3) 有可能是 true 吗?

1. 利用松散相等运算符 == 的原理,自定义 toString 和 valueOf 返回对应值2. 利用半宽度韩文等特殊字符,玩“障眼法”,本质上其实并没有做到题设3. 劫持 JS 对象的 getter,不过这种方式对于严格相等 === 同样有效

js中~~和 | 的妙用

~~它代表双非按位取反运算符,如果你想使用比Math.floor()更快的方法,那就是它了。需要注意,对于正数,它向下取整;对于负数,向上取整;非数字取值为0,它具体的表现形式为:

js技巧_js中一些常见的陷阱

这里我们针对JavaScript初学者给出一些技巧和列出一些陷阱。如果你已经是一个砖家,也可以读一读。你是否尝试过对数组元素进行排序?

5个小技巧让你写出更好的 JavaScript 条件语句

使用 Array.includes 来处理多重条件,少写嵌套,尽早返回,使用函数默认参数和解构,相较于 switch,Map / Object 也许是更好的选择,使用 Array.every 和 Array.some 来处理全部/部分满足条件,让我们一起写出可读性更高的代码吧

js语言中常见错误总汇

事实证明很多这些 null 或 undefined 的错误是普遍存在的。 一个类似于 Typescript 这样的好的静态类型检查系统,当设置为严格的编译选项时,能够帮助开发者避免这些错误。

js求数组的最大值--奇技淫巧和笨方法

js中有很多“奇技淫巧”,有时我会常常刻意去用这些“奇技淫巧”(注意,我不是在反对用它,只是有时其实没必要用)。比如,求数组中的最大值,js中Array没有原生的求最大值的方法,但是Math有呀

一些 JavaScript 中的代码小技巧

一些 JavaScript 中的代码小技巧:使用函数过滤并序列化对象、用 Set 来实现数组去重、用块级作用域避免命名冲突、函数参数值校验、用解构赋值过滤对象属性、用解构赋值获取嵌套对象的属性、合并对象、使用 === 代替 ==

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!

文章投稿关于web前端网站点搜索站长推荐网站地图站长QQ:522607023

小程序专栏: 土味情话心理测试脑筋急转弯幽默笑话段子句子语录成语大全运营推广