JS禁止打开控制台

6 篇文章 0 订阅

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


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调式,那么就毫无意义了。
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-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函数

6、练手网站推荐

下面推荐几个网站,他们都用了上面讲的某种方法来禁止打开控制台,感兴趣的话可以研究下他们是怎么做到的,该如何破解(破解方法在上面已经给出了)。

以下网站推荐不具有针对性,如有冒犯,十分抱歉,可联系我进行删除

1、http://marsgis.cn/project/3d/...

2、https://z1.m1907.cn/

3、https://music.qugeek.com/page...

 

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第一部分 JavaScript入门 1 第1章 编写第一个JavaScript程序 1 1.1 编程简介 1 什么是计算机程序 2 1.2 如何把JavaScript添加到页面 3 外部JavaScript文件 5 1.3 第一个JavaScript程序 7 1.4 把文本写到Web页面上 9 1.5 附件外部JavaScript文件 10 1.6 追踪错误 12 1.6.1 Firefox JavaScript控制台 13 1.6.2 显示Internet Explorer错误对话框 14 1.6.3 访问Safari错误控制台 15 第2章 JavaScript的语法 16 2.1 语句 16 2.2 命令 16 2.3 数据类型 17 2.3.1 数值 17 2.3.2 字符串 18 2.3.3 Boolean 19 2.4 变量 19 2.4.1 创建变量 20 2.4.2 使用变量 22 2.5 操作数据类型和变量 23 2.5.1 基本算术 24 2.5.2 操作的顺序 25 2.5.3 组合字符串 25 2.5.4 组合数值和字符串 26 2.5.5 修改变量中的值 27 2.6 教程:使用变量创建消息 28 2.7 教程:请求信息 30 2.8 数组 32 2.8.1 创建数组 32 2.8.2 访问数组中的项目 34 2.8.3 向数组添加项目 35 2.8.4 从数组删除项目 37 2.8.5 使用splice( )添加和删除 38 2.9 教程:编写使用数组的页面 40 2.10 注释 42 2.10.1 何时使用注释 43 2.10.2 本书中的注释 44 第3章 为程序添加逻辑和控制 45 3.1 使程序智能地响应 45 3.1.1 条件语句基础 46 3.1.2 添加备用计划 49 3.1.3 测试多个条件 49 3.1.4 更复杂的条件 51 3.1.5 嵌套条件语句 53 3.1.6 编写条件语句的技巧 54 3.2 教程:使用条件语句 55 3.3 使用循环处理重复性任务 58 3.3.1 while循环 58 3.3.2 循环和数组 60 3.3.3 for循环 61 3.3.4 do/while循环 63 3.4 函数:把有用的代码转换为可复用的命令 64 3.4.1 小教程 66 3.4.2 给函数提供信息 67 3.4.3 从函数获取信息 69 3.4.4 防止变量冲突 70 3.5 教程:一个简单测验 72 第4章 操作字符串、数值和日期 77 4.1 快速对象介绍 78 4.2 字符串 80 4.2.1 确定字符串的长度 80 4.2.2 改变字符串的大小写 80 4.2.3 查找一个字符串:indexOf( )技术 81 4.2.4 使用slice( )提取字符串的一部分 83 4.3 在字符串中查找模式 84 4.3.1 创建和使用基本的正则表达式 84 4.3.2 构建一个正则表达式 85 4.3.3 分组正则表达式的部分 88 4.3.4 有用的正则表达式 89 4.3.5 匹配模式 94 4.3.6 替换文本 96 4.3.7 尝试正则表达式 97 4.4 数值 97 4.4.1 把字符串改变为数值 97 4.4.2 测试数值 99 4.4.3 舍入数值 100 4.4.4 格式化货币值 100 4.4.5 创建随机数 101 4.5 日期和时间 103 4.5.1 获取月份 103 4.5.2获取星期几 104 4.5.3 获取时间 105 4.5.4 创建当前日期之外的日期 108 4.6 教程 109 4.6.1 概览 109 4.6.2 编写函数 110 第5章 动态修改Web页面 115 5.1 修改Web页面:概览 116 5.2 理解文档对象模型 117 5.2.1 选择页面元素 118 5.2.2 给页面添加内容 122 5.2.3 再谈月球测验 123 5.2.4 DOM的问题 126 5.3 JavaScript库简介 127 初学jQuery 128 5.4 再谈选择页面元素 129 5.4.1 基本选择器 130 5.4.2 高级选择器 133 5.4.3 jQuery过滤器 135 5.4.4 理解jQuery选择 136 5.5 向页面添加内容 138 替换和删除选择 141 5.6 设置和读取标签属性 142 5.6.1 类 142 5.6.2 读取和改变CSS属性 143 5.6.3 一次改变多个CSS属性 145 5.7 读取、设置和删除HTML属性 146 5.8 创意标题 147 5.9 操作选择中的每个元素 149 5.9.1 匿名函数 150 5.9.2 this和$(this) 150 5.10 自动提取引用 152 5.10.1 概览 152 5.10.2 编程 153 第6章 动作/响应:让页面通过事件活动起来 156 6.1 什么是事件 156 6.1.1 鼠标事件 158 6.1.2 文档/窗口事件 159 6.1.3 表单事件 160 6.1.4 键盘事件 160 6.2 把函数和事件一起使用 161 6.2.1 内联事件 161 6.2.2 传统模型 162 6.2.3 现代方式 163 6.2.4 jQuery方式 164 6.3 教程:突出显示表格行 167 6.4 更多的jQuery事件概念 171 6.4.1 等待HTML载入 171 6.4.2 jQuery事件 173 6.4.3 事件对象 175 6.4.4 阻止事件的常规行为 176 6.4.5 删除事件 177 6.5 高级事件管理 178 6.6 教程:一页的FAQ 180 6.6.1 任务概览 180 6.6.2 编程 180 第7章 改进图像 184 7.1 交换图像 184 7.1.1 改变图像的src属性 184 7.1.2 预载入图像 186 7.1.3 翻滚图像 187 7.2 教程:添加翻滚图像 188 7.2.1 任务概览 189 7.2.2 编程 189 7.3 jQuery效果 192 7.3.1 基本显示和隐藏 193 7.3.2 淡入淡出元素 194 7.3.3 滑动元素 195 7.3.4 动画 195 7.4 教程:带有效果的照片集 197 7.4.1 任务概览 197 7.4.2 编程 198 7.5 使用jQuery lightBox的高级照片集 201 7.5.1 基础 202 7.5.2 定制lightBox 204 7.6 教程:lightBox照片集 207 7.7 使用Cycle实现幻灯片动画 209 7.7.1 基础 209 7.7.2 定制Cycle插件 211 7.8 教程:一个自动的幻灯片 214 第二部分 构建Web页面功能 218 第8章 改进导航 218 8.1 一些链接基础知识 218 8.1.1 用JavaScript选择链接 218 8.1.2 确定链接的目标 219 8.1.3 不要打开链接 220 8.2 在新窗口中打开外部链接 221 8.3 创建新窗口 224 窗口属性 224 8.4 在页面上的一个窗口中打开页面 228 8.4.1 定制Greybox窗口的外观 231 8.4.2 教程:在页面中打开一个页面 232 8.5 教程:生成较大链接 235 8.5.1 概览 235 8.5.2 编程 237 8.6 实现导航菜单动画 241 8.6.1 HTML 242 8.6.2 CSS 243 8.6.3 JavaScript 243 8.6.4 教程 244 第9章 扩展Web表单 247 9.1 理解表单 248 9.1.1 选择表单元素 249 9.1.2 获取和设置表单元素的值 251 9.1.3 确定按钮和选框是否选中 252 9.1.4 表单事件 253 9.2 为表单添加智能 257 9.2.1 聚焦表单的第一个字段 257 9.2.2 关闭或打开字段 258 9.2.3 隐藏和显示表单选项 260 9.3 教程:基本表单扩展 260 9.3.1 聚焦到一个字段 261 9.3.2 关闭表单字段 261 9.3.3 隐藏表单字段 265 9.4 表单验证 266 9.4.1 jQuery Validation插件 267 9.4.2 基本验证 269 9.4.3 高级验证 271 9.4.4 样式化错误消息 277 9.5 验证教程 278 9.5.1 基本验证 278 9.5.2 高级验证 280 9.5.3 验证复选框和单选按钮 283 9.5.4 格式化错误消息 286 第10章 扩展界面 287 10.1 使用折叠面板隐藏信息 287 10.1.1 定制Accordion 290 10.1.2 折叠教程 293 10.2 把信息组织到标签页面板 295 10.2.1 格式化标签页和面板 298 10.2.2 定制Tabs插件 300 10.2.3 标签页面板教程 302 10.3 工具提示 305 10.3.1 使用title属性的工具提示 306 10.3.2 使用其他Web页面的工具提示 308 10.3.3 使用隐藏内容的工具提示 309 10.3.4 控制工具提示的显示 311 10.3.5 格式化工具提示 315 10.3.6 Cluetip教程 316 10.4 创建可排序表格 321 10.4.1 样式化表格 324 10.4.2 Tablesorter教程 325 第三部分 Ajax:与Web服务器通信 327 第11章 初识Ajax 327 11.1 什么是Ajax 328 11.2 Ajax基础知识 329 11.2.1 拼图块 329 11.2.2 和Web服务器通信 331 11.3 Ajax的jQuery方式 334 11.3.1 使用load( )函数 335 11.3.2 教程:load( )函数 336 11.3.3 get( )和post( )函数 339 11.3.4 格式化发送给服务器的数据 341 11.3.5 处理来自服务器的数据 343 11.3.6 教程:使用get( )函数 347 11.4 JSON 351 11.4.1 访问JSON数据 353 11.4.2 复杂的JSON对象 354 第12章 Ajax编程基础 357 12.1 Tabs插件 357 12.1.1 改变正在加载文本和图标 359 12.1.2 Ajax标签页教程 361 12.2 向站点添加Google地图 364 12.2.1 为地图设定位置 366 12.2.2 其他jMaps选项 367 12.2.3 添加标志和HTML提示提示框 369 12.2.4 获取驱车指示 370 12.2.5 jMaps教程 371 第四部分 除错、提示和技巧 377 第13章 除错和调试 377 13.1 常见JavaScript编程错误 377 13.1.1 没有结束符号 377 13.1.2 引号 381 13.1.3 使用保留字 382 13.1.4 条件语句中的单个等号 383 13.1.5 区分大小写 384 13.1.6 外部JavaScript文件的路径不正确 384 13.1.7 外部JavaScript文件中的不正确路径 385 13.1.8 消失的变量和函数 386 13.2 使用Firebug调试 387 13.2.1 安装并打开Firebug 387 13.2.2 用Firebug查看错误 388 13.2.3 使用console.log( )记录脚本过程 389 13.2.4 教程:使用Firebug控制台 390 13.2.5 更强大的调试 393 13.3 调试教程 397 第14章 深入JavaScript 401 14.1 综合应用 401 使用外部JavaScript文件 401 14.2 编写更高效的JavaScript 403 14.2.1 优先使用变量 403 14.2.2 三元操作符 405 14.2.3 switch语句 406 14.2.4 高效地使用jQuery对象 409 14.3 创建快速载入的JavaScript 410 14.3.1 在Windows下使用YUI Compressor 411 14.3.2 在Mac下使用YUI Compressor 412 第五部分 附录 413 附录A JavaScript资源 413

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值