Frontend Development 5 min read

Techniques for Preventing Debugging in Front‑End JavaScript Applications

This article explains why front‑end developers may want to block debugging, demonstrates how infinite `debugger` statements can be used to hinder inspection, and provides multiple counter‑measures—including disabling breakpoints, using `Function('debugger')`, code obfuscation, and an advanced anti‑debug script that detects window size anomalies.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Techniques for Preventing Debugging in Front‑End JavaScript Applications

Front‑end pages often call many APIs, and some interfaces can be analyzed by crawlers to extract data; therefore, developers may want to prohibit debugging to prevent such data leakage, and the simplest method is to block users from inspecting the front‑end code.

The most common anti‑debug technique is to insert an infinite loop of debugger statements using setInterval . When the console is open, each debugger triggers a breakpoint, effectively disabling normal debugging and hiding network requests.

/**
 * 基础禁止调试代码
 */
(() => {
  function ban() {
    setInterval(() => {
      debugger;
    }, 50);
  }
  try {
    ban();
  } catch (err) {}
})();

One counter‑measure is to use the DevTools "Deactivate breakpoints" button or the shortcut Ctrl + F8 to stop the infinite debugger . However, this does not allow adding breakpoints via the line numbers on the left.

Another approach is to compress the setInterval code into a single line, making logpoints ineffective; even formatting the code into multiple lines does not bypass the protection.

Developers can also add an "script ignore list" to skip execution of specific lines or files, which can also block the infinite debugger statements.

For more resilient protection, the debugger call can be rewritten as Function("debugger")() . This uses the Function constructor to generate a temporary JavaScript file each time, making it harder to detect and stop.

// 加密前
(() => {
  function ban() {
    setInterval(() => {
      Function('debugger')();
    }, 50);
  }
  try { ban(); } catch (err) {}
})();

// 加密后
eval(function(c,g,a,b,d,e){d=String;if(!"".replace(/^/,String)){for(;a--;)e[a]=b[a]||a;b=[function(f){return e[f]}];d=function(){return"\w+"};a=1}for(;a--;)b[a]&& (c=c.replace(new RegExp("\b"+d(a)+"\b","g"),b[a]));return c}('(...code...)',9,9,"block function setInterval Function debugger 50 try catch err".split(" "),0,{}));

The ultimate enhanced anti‑debug script adds a check on the difference between window.outerHeight/outerWidth and window.innerHeight/innerWidth . If the difference exceeds a threshold, it replaces the page body with a warning message. It then repeatedly executes (function(){return false;})['constructor']('debugger')['call'](); inside a setInterval to keep the debugger blocked.

(() => {
  function block() {
    if (window.outerHeight - window.innerHeight > 200 || window.outerWidth - window.innerWidth > 200) {
      document.body.innerHTML = "检测到非法调试,请关闭后刷新重试!";
    }
    setInterval(() => {
      (function(){return false;})['constructor']('debugger')['call']();
    }, 50);
  }
  try { block(); } catch (err) {}
})();

Using such obfuscated and optionally encrypted scripts provides a stronger defense against unwanted debugging, though developers should weigh the impact on maintainability and user experience.

frontendJavaScriptobfuscationsecurityDebuggeranti-debugging
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.