JS禁止打開控制檯

主要爲了經過禁止打開控制檯,防止別人進行代碼調試。javascript


一、禁止右鍵查看源碼和F12

//禁止F12鍵盤事件
document.addEventListener('keydown', function(event){
   return 123 != event.keyCode || (event.returnValue = false)
});
//禁止右鍵、選擇、複製
document.addEventListener(‘'contextmenu'’, function(event){
   return event.returnValue = false
})

破解:還可使用瀏覽器菜單中的開發者工具打開控制檯html

二、經過頁面寬度變化監測控制檯

瀏覽寬高變化監測主要是監測瀏覽器可視區域的寬高:window.innerWidth / window.innerHeight(滾動條和內容區)和瀏覽器寬高:window.outerWidth / window.outerHeight(inner的基礎上加上工具條的寬高)之間的差值。java

由於咱們不知道瀏覽器是否開啓了工具條及工具條的寬高,因此咱們設置一個閾值如200,若是outer – inner 大於200,咱們就認爲開啓了控制檯。git

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...,感興趣的能夠去看一下。github

破解:監測瀏覽器寬高變化的缺點是很是明顯的,由於這種監測只能針對控制檯內嵌的情形,可是不少瀏覽器都支持獨立窗口式的控制檯。chrome

三、利用控制檯特性改寫對象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(){}}};)。app

四、利用控制檯特性進行監聽dom屬性

大部分瀏覽器在打印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,可是若是被觸發,那間隔時間就不是幾10、幾百毫秒了。

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:
chrome.png
Firefox:
firefox.png

彙總三、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瀏覽器、搜狗瀏覽器)

五、利用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函數

六、練手網站推薦

下面推薦幾個網站,他們都用了上面講的某種方法來禁止打開控制檯,感興趣的話能夠研究下他們是怎麼作到的,該如何破解(破解方法在上面已經給出了)。

如下網站推薦不具備針對性,若有冒犯,十分抱歉,可聯繫我進行刪除

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

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

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

相關文章
相關標籤/搜索