piapia123
zh

JS 压缩混淆

格式化

所有处理都在浏览器本地完成,数据不上传服务器

输入
把文件拖到这里可直接载入
输出

把 JavaScript 压得更小、更不好读:去注释、去空白、字符串转义、数字转十六进制、局部变量换成短名。 ⚠️ 先说最重要的一句:混淆保护不了代码。 任何能在浏览器里跑起来的 JavaScript,都能被人读懂。改名和转义改变的是「看起来费不费劲」,而代码的结构(有几个函数、谁调用谁、判断怎么走)一点没变 —— 结构才是信息量所在。反混淆工具格式化一下、猜几个名字,就能还原出可读版本,成本远低于混淆的成本。所以真正要紧的东西 —— 密钥、核心算法、鉴权判断 —— 只能放在服务端,放前端就是公开的。 那这个工具的意义在哪?两个务实的场景:减小体积(去掉注释空白、缩短局部变量名,省下的字节是实打实的),以及抬高随手一看的门槛(让人点开「查看源代码」时不至于一眼看穿业务逻辑)。把它当成一个「带点混淆效果的压缩器」,期望就对了。 重命名做得极其保守,宁可少改也不改错:顶层作用域一律不动(它可能是导出,也可能是被页面里其他 `<script>` 共享的全局),出现 `eval`、`with`、动态 `import()` 就整体放弃改名(这三样能在运行时拼出变量名,静态分析无从下手),新名字也绝不与代码里出现的任何名字重复。万一还是改了不该改的地方,代价是代码运行结果出错而不是报错 —— 所以这里每条语法边界都配了「混淆前后跑一遍比结果」的测试。

功能

  • 去掉全部注释与多余空白
  • 字符串转成十六进制或 Unicode 转义(中文自动走 \u,不会拆错字节)
  • 数字字面量转十六进制
  • 局部变量重命名为 `a`、`b`、`c` … 顶层名字保持不动
  • 可选:删掉 `console.*` 调用
  • 给出体积变化与改名数量
  • ⚠️ 不保护代码 —— 页面上也这样写,原因见下方问答

使用方法

  1. 把 JavaScript 代码粘贴到左侧
  2. 按需勾选重命名、字符串编码、数字与 console 处理
  3. 按 Ctrl/⌘ + Enter 或点「运行」
  4. 用第一行右侧的按钮复制混淆后的代码

常见问题

混淆之后,代码就安全了吗?
没有。 这是关于这类工具最需要说清楚的一件事。 JavaScript 要在用户的浏览器里执行,就必须把源码交给浏览器;而交给浏览器的东西,用户就一定拿得到。混淆只是让这段源码难读一点,不是让它读不到 —— 这两件事经常被混为一谈。 具体到本工具做的几件事:改名字只是换了个称呼,调用关系、循环结构、条件分支原封不动;字符串转义在浏览器里运行时会被原样解回来,粘贴进控制台执行一下就看到了。市面上更强的混淆(控制流平坦化、字符串数组加密、反调试)确实能让人多花几个小时,但对应的反混淆工具也在同步进化,而代价是你的线上报错堆栈变成一堆 `a`、`b`、`c`,出了问题几乎没法定位。 结论:需要保密的东西,不要放到前端。 密钥、签名逻辑、业务规则都应该在服务端执行,前端只调用接口。
为什么有些变量没被改名?
几种情况都是故意的。顶层声明一律不动 —— 它可能是模块的导出(外部要按这个名字引用),也可能是和页面里其他脚本共享的全局变量,两者从代码本身都看不出来。`import` 进来的名字不动,它指向别的模块的导出。属性名一律不动(`obj.userName` 里的 `userName`),因为改了它就会去读一个不存在的属性 —— 而且 `obj.userName` 改了、`obj["userName"]` 没改的话,两者的结果会不一致。 另外,如果代码里出现了 `eval`、`with` 或动态 `import()`,整个文件都会放弃改名 —— 这三样能在运行时按字符串拼出变量名,静态分析根本追不上。结果区会明确写出来是哪一条触发的。
混淆完的代码还能正常运行吗?
能,语义完全不变 —— 改名与转义都是保义变换,输出与输入在行为上逐位等价。 不过这件事没有「理论上正确」这么简单:改名唯一可能犯的错是「改到了不该改的地方」,而那种错不会报错,只是结果悄悄变了。所以测试里配了大量「同一段代码,混淆前后各跑一遍,结果必须相同」的用例,专门覆盖闭包捕获、解构(含简写 `{x}`、带默认值 `{x = 1}`)、`for (let)` 的每轮绑定、带标签的跳转、`class` 的 getter、可选链、模板字符串、正则、BigInt 这些容易踩的地方。 仍然建议:混淆后的代码先在本地跑一遍测试再发布。它可能暴露的是你的测试覆盖不到的路径。

相关工具