如何避免用户通过浏览器控制台查看页面资源

2022-09-21 09:30:34 浏览数 (1)

代码如下,复制到全局作用域即可用

代码语言:javascript复制
const ConsoleGuard = {
    // 该方法用于跳转空白页面
    openCallback() {
        try {
            window.open('about:blank', '_self');
        }
        catch (e) {
            const btn = document.createElement('button');
            btn.addEventListener('click', () => {
                window.open('about:blank', '_self');
            });
            btn.click();
        }
    },
    // 该方法适用于Safari浏览器,由于尝试在Safari中debugger无效,所以需要单独写
    observeSafari() {
        const div = document.createElement('div');
        // 定义DOM节点对象属性的修饰符,当节点id被读取时,跳转空白页
        Object.defineProperty(div, 'id', {
            get: () => {
                this.openCallback();
            },
        });
        // 在Safari等部分浏览器中,打印一个DOM节点时,如果控制台开启,浏览器会读取上面的属性,否则不会
        console.log(div);
    },
    observe() {
        const obj = Object.create(null);
        // 记录当前时间
        let t = Date.now();
        // 修改对象属性的取值方法
        Object.defineProperty(obj, 'a', {
            get: () => {
                // 当对象属性的取值方法被触发时,判断时间间隔是否大于100ms
                if (Date.now() - t > 100) {
                    // 如果打开了控制台,将弹出debugger,时间间隔一定会大于100ms,此时跳转空白页
                    this.openCallback();
                }
            },
        });

        // 定时打印obj.a触发属性的get方法进行判断
        setInterval(() => {
            // 更新时间t,关键点
            t = Date.now();
            // debugger,如果控制台开启,则会弹出debugger,否则不会
            (function debug() {}).constructor('debugger')(); // debugger
            // 触发obj.a的get方法
            console.log(obj.a);
        }, 200);
    },
    init() {
        const userAgent = window.navigator.userAgent.toLowerCase();
        if (userAgent.includes('safari') && !userAgent.includes('chrome')) {
            this.observeSafari();
        }
        else {
            this.observe();
        }
    },
};

ConsoleGuard.init();

代码思想很简单,就是打开控制台时,将页面跳转到空白页,关键在于判断控制台是否被打开。 这里写了两个方法,一个是适用于Safari的observeSafari,另一个是适用于Chrome、Firefox等浏览器的observe方法。

在Safari中,打印一个DOM节点时,如果控制台被打开,则会读取节点的属性;如果没有,则不会读取。因此,只需要在节点对象属性的取值修饰符中写入跳转空白页的代码即可。这样,当控制台被打开时,打印DOM节点时将读取节点属性,由于我们在属性的get方法中写入了跳转空白页面的代码,所以在调用属性的取值方法时会进行跳转。

在Chrome、Firefox等浏览器中需要借助debugger来实现该功能,因此如果用户手动关闭了debug,功能将失效。

debugger用于在JS代码中设置断点,只有在控制台打开时debugger才会起作用。因此我们可以借助一个定时器来实现功能。定时器的定时任务中记录一下该段代码执行的起始时间,之后进行debugger,在任务结束时用结束时间减去起始时间获得该任务执行的总时长。如果总时长大于或等于人手关闭debugger的最小时长,比如100ms,则认为执行了debugger。由于debugger只有在控制台打开时才会执行,所以此时可认为打开了控制台。

ios

0 人点赞