Detect when “Inspect Element” is open

后端 未结 1 1741
感动是毒
感动是毒 2020-12-07 11:44

Samy Kamkar\'s website, http://samy.pl, knows when the console is being opened and wipes the source/console when it does open.

How does this work?

相关标签:
1条回答
  • 2020-12-07 12:04

    This took some digging. samy.pl has several levels of indirection and obfuscation on top of this code. It uses a different version of the detection code than the GitHub repository found by JohanP. The code in samy.pl, unlike the GitHub repository, can detect the devtools when they are not docked.

    It does so by using a short script that executes differently depending on whether devtools is open or closed.

    Example script

    Here's a self-contained example; open it in a browser and notice how the output changes as the devtools are opened and closed (whether it is docked or not):

    <!DOCTYPE html>
    <html>
        <body>
            <pre id="output"></pre>
            <script type="text/javascript">
                var element = new Image;
                var devtoolsOpen = false;
                element.__defineGetter__("id", function() {
                    devtoolsOpen = true; // This only executes when devtools is open.
                });
                setInterval(function() {
                    devtoolsOpen = false;
                    console.log(element);
                    document.getElementById('output').innerHTML += (devtoolsOpen ? "dev tools is open\n" : "dev tools is closed\n");
                }, 1000);
            </script>
        </body>
    </html>
    

    How it works

    The setInterval is executed every second. console.log always executes, whether the devtools are open or closed: The console object is always defined. However, the log method only writes output to the console when the devtools are open. If the devtools are closed, console.log is a no-op. That's the key that lets you detect if the devtools are open: detecting if the log operation is a no-op.

    In the process of writing element to the console, it gets the id of the element. That calls the function attached with __defineGetter__. Therefore, console.log(element) only calls that function when the devtools are open and console.log is not a no-op. The flag is set in that function, giving us an updated view of the devtools state every second.

    samy.pl uses some additional tricks to hide this: the console is also cleared every second, and this code is obfuscated with a whitespace (!) encoding.

    0 讨论(0)
提交回复
热议问题