文章列表

如何判断用户是否离开了当前页面?

作者:微信小助手

<p data-line="1" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; data-pm-slice="0 0 []"><span leaf="">在现代 Web 开发中,我们常常需要知道用户是否还停留在当前页面。这个看似简单的需求,背后却关联着用户体验、数据分析和系统性能等多个重要方面。</span></p> <p data-line="3" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">“离开页面”这个行为本身可以被细分为多种场景:</span></p> <ol style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">切换到其他浏览器标签页或应用</span></strong><span leaf="">(页面变为不可见,但未关闭)。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">最小化浏览器窗口</span></strong><span leaf="">(同上)。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">关闭浏览器标签页或整个浏览器</span></strong><span leaf="">。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">在当前标签页中导航到新的 URL</span></strong><span leaf="">。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">在移动设备上切换到其他 App 或返回主屏幕</span></strong><span leaf="">。</span></span></li> </ol> <p data-line="10" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">针对这些不同的场景,前端提供了多种不同的技术和 API 来进行判断。</span></p> <h2 data-line="12" style="box-sizing: border-box;margin-top: 1.2em;margin-bottom: 16px;font-weight: 400;line-height: 1.2;color: rgb(0, 0, 0);font-size: 1.4641em;padding-bottom: 0.2em;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">方法一:Page Visibility API (页面可见性 API) - 现代首选</span></h2> <p data-line="14" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">这是处理“页面是否对用户可见”这一问题的标准方法。它专门用于检测页面是否被隐藏或显示,非常适合处理用户切换标签页、最小化窗口等场景。</span></p> <p data-line="16" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">核心概念:</span></strong></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">document.hidden</span></code></strong><span leaf="">:一个只读属性,如果页面处于后台或最小化状态,则返回&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">true</span></code><span leaf="">,否则返回&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">false</span></code><span leaf="">。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">visibilitychange</span></code><span leaf="">&nbsp;事件</span></strong><span leaf="">:当页面的可见性状态发生变化时(即&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">document.hidden</span></code><span leaf="">&nbsp;的值改变时),该事件会在&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">document</span></code><span leaf="">&nbsp;对象上触发。</span></span></li> </ul> <p data-line="20" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">适用场景:</span></strong></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><span leaf="">暂停/播放视频或音频。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><span leaf="">停止/启动动画或轮播图。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><span leaf="">暂停轮询服务器请求,在页面恢复可见时再继续。</span></span></li> </ul> <p data-line="25" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">代码示例:</span></strong></p> <pre style="box-sizing: border-box;font-family: SFMono-Regular, Menlo, Monaco, Consolas, " liberation mono, courier new, monospace;font-size: 0.875em;display: block;margin-top: 0px;margin-bottom: 1rem;overflow: auto;color: rgb(51, 51, 51);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><code style="box-sizing: border-box;font-family: " fira code, menlo, consolas, source code pro, monospace;font-size: 14px;color: rgb(51, 51, 51);overflow-wrap: break-word;padding: 0.5em;margin: 0px;background: rgb(248, 248, 248);border-radius: 3px;word-break: normal;display: block;overflow-x: auto;><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">document</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">addEventListener</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'visibilitychange'</span></span><span leaf="">,</span><span style="box-sizing: border-box;"><span leaf="">&nbsp;() =&gt;</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;color: rgb(51, 51, 51);font-weight: bold;"><span leaf="">&nbsp;if</span></span><span leaf="">&nbsp;(</span><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">document</span></span><span leaf="">.</span><span style="box-sizing: border-box;"><span leaf="">hidden</span></span><span leaf="">) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 153, 136);font-style: italic;"><span leaf="">&nbsp;// 页面变得不可见</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">&nbsp;console</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">log</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'用户离开了当前页面(切换标签页或最小化)'</span></span><span leaf="">);</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 153, 136);font-style: italic;"><span leaf="">&nbsp;// 在这里暂停视频、动画等</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">&nbsp;pauseMyVideo</span></span><span leaf="">();</span><span leaf=""><br></span><span leaf="">&nbsp; }</span><span style="box-sizing: border-box;color: rgb(51, 51, 51);font-weight: bold;"><span leaf="">&nbsp;else</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 153, 136);font-style: italic;"><span leaf="">&nbsp;// 页面恢复可见</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">&nbsp;console</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">log</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'用户回到了当前页面'</span></span><span leaf="">);</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 153, 136);font-style: italic;"><span leaf="">&nbsp;// 在这里恢复播放</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">&nbsp;playMyVideo</span></span><span leaf="">();</span><span leaf=""><br></span><span leaf="">&nbsp; }</span><span leaf=""><br></span><span leaf="">});</span><span leaf=""><br></span></code></pre> <p data-line="42" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">优点:</span></strong></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">标准、可靠</span></strong><span leaf="">:W3C 标准,所有现代浏览器都支持。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">性能友好</span></strong><span leaf="">:专门为此设计,能有效节省 CPU 和电池资源。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">逻辑清晰</span></strong><span leaf="">:直接反映页面的“可见”状态。</span></span></li> </ul> <p data-line="47" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">缺点:</span></strong></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><span leaf="">它无法判断用户是否正在</span><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">关闭</span></strong><span leaf="">页面。当用户关闭标签页时,</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">visibilitychange</span></code><span leaf="">&nbsp;事件可能会触发(变为 hidden),但我们无法区分这是切换还是关闭。</span></span></li> </ul> <hr style="box-sizing: border-box;margin: 1rem 0px;color: rgb(51, 51, 51);border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-image: initial;border-top-style: solid;border-top-color: rgb(51, 51, 51);opacity: 0.25;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;> <h2 data-line="52" style="box-sizing: border-box;margin-top: 1.2em;margin-bottom: 16px;font-weight: 400;line-height: 1.2;color: rgb(0, 0, 0);font-size: 1.4641em;padding-bottom: 0.2em;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">方法二:</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 19.9118px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">beforeunload</span></code><span leaf="">&nbsp;和&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 19.9118px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;事件 - 传统告别方式</span></h2> <p data-line="54" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">这两个事件是在用户即将</span><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">真正离开</span></strong><span leaf="">页面(关闭、刷新、导航到其他链接)时触发的。</span></p> <h3 data-line="56" style="box-sizing: border-box;margin-top: 1.2em;margin-bottom: 16px;font-weight: 500;line-height: 1.2;color: rgb(0, 0, 0);font-size: 1.331em;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">1.&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 18.1016px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">beforeunload</span></code><span leaf="">&nbsp;事件</span></h3> <p data-line="57" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">该事件在窗口、文档及其资源即将被卸载时触发。它可以用来询问用户是否确定要离开。</span></p> <p data-line="59" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">核心用途:</span></strong></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><span leaf="">防止用户意外丢失未保存的数据。浏览器通常会弹出一个确认对话框。</span></span></li> </ul> <p data-line="62" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">代码示例:</span></strong></p> <section nodeleaf=""> <img src="/upload/7abe38fefd47b2cbaeb1e266365c9e2d.png" class="rich_pages wxw-img" data-ratio="0.31443298969072164" data-type="png" data-w="776" style="box-sizing: border-box;vertical-align: middle;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;max-width: 100%; data-imgfileid="504023176"> </section> <section> <span style="color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;display: inline !important;float: none;></span> </section> <p data-line="72" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">注意</span></strong><span leaf="">:出于安全考虑,现代浏览器不允许开发者自定义提示框中的文本内容,只会显示浏览器内置的标准化提示。</span></p> <h3 data-line="74" style="box-sizing: border-box;margin-top: 1.2em;margin-bottom: 16px;font-weight: 500;line-height: 1.2;color: rgb(0, 0, 0);font-size: 1.331em;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">2.&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 18.1016px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;事件</span></h3> <p data-line="75" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">该事件在页面</span><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">已经开始卸载</span></strong><span leaf="">之后触发。这是我们在用户离开时执行最后清理操作的传统位置。</span></p> <p data-line="77" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">代码示例:</span></strong></p> <pre style="box-sizing: border-box;font-family: SFMono-Regular, Menlo, Monaco, Consolas, " liberation mono, courier new, monospace;font-size: 0.875em;display: block;margin-top: 0px;margin-bottom: 1rem;overflow: auto;color: rgb(51, 51, 51);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><code style="box-sizing: border-box;font-family: " fira code, menlo, consolas, source code pro, monospace;font-size: 14px;color: rgb(51, 51, 51);overflow-wrap: break-word;padding: 0.5em;margin: 0px;background: rgb(248, 248, 248);border-radius: 3px;word-break: normal;display: block;overflow-x: auto;><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">window</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">addEventListener</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'unload'</span></span><span leaf="">,</span><span style="box-sizing: border-box;"><span leaf="">&nbsp;() =&gt;</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">&nbsp;console</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">log</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'用户正在关闭或离开页面'</span></span><span leaf="">);</span><span leaf=""><br></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 153, 136);font-style: italic;"><span leaf="">&nbsp;// 警告:在这里执行的操作可能不会完成!</span></span><span leaf=""><br></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 153, 136);font-style: italic;"><span leaf="">&nbsp;// sendAnalyticsData();</span></span><span leaf=""><br></span><span leaf="">});</span><span leaf=""><br></span></code></pre> <p data-line="86" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">重大缺陷:</span></strong><span leaf=""><br></span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;事件非常</span><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">不可靠</span></strong><span leaf="">。浏览器在处理页面卸载时,并不会等待&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;事件处理器中的异步操作(如&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">fetch</span></code><span leaf="">&nbsp;或&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">XMLHttpRequest</span></code><span leaf="">)完成。这意味着,如果我们想在这里发送一个分析数据到服务器,这个请求很可能在发送完成之前就被浏览器终止了。</span></p> <hr style="box-sizing: border-box;margin: 1rem 0px;color: rgb(51, 51, 51);border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-image: initial;border-top-style: solid;border-top-color: rgb(51, 51, 51);opacity: 0.25;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;> <h2 data-line="91" style="box-sizing: border-box;margin-top: 1.2em;margin-bottom: 16px;font-weight: 400;line-height: 1.2;color: rgb(0, 0, 0);font-size: 1.4641em;padding-bottom: 0.2em;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">方法三:</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 19.9118px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">navigator.sendBeacon()</span></code><span leaf="">&nbsp;- 可靠的数据上报利器</span></h2> <p data-line="93" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">为了解决&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;事件中异步请求不可靠的问题,W3C 推出了&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">navigator.sendBeacon()</span></code><span leaf="">&nbsp;API。</span></p> <p data-line="95" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">核心概念:</span></strong><span leaf=""><br></span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">sendBeacon()</span></code><span leaf="">&nbsp;方法可以异步地向服务器发送少量数据,并且</span><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">浏览器保证</span></strong><span leaf="">会将其启动并排队发送,而不会阻塞或延迟页面的卸载过程。即使页面已经关闭,数据发送也会在后台继续进行。</span></p> <p data-line="98" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">适用场景:</span></strong></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><span leaf="">在用户离开页面时,可靠地发送日志、分析或统计数据。</span></span></li> </ul> <p data-line="101" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">如何使用(通常与&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;或&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code><span leaf="">&nbsp;结合):</span></strong></p> <section nodeleaf=""> <img src="/upload/cb0cf12e8100ae39619c33fdc14c71f3.png" class="rich_pages wxw-img" data-ratio="0.22407407407407406" data-type="png" data-w="1080" style="box-sizing: border-box;vertical-align: middle;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;max-width: 100%; data-imgfileid="504023178"> </section> <section> <span style="color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;display: inline !important;float: none;></span> </section> <p data-line="113" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">这种方式是目前在页面卸载时发送数据的</span><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">最佳实践</span></strong><span leaf="">。</span></p> <hr style="box-sizing: border-box;margin: 1rem 0px;color: rgb(51, 51, 51);border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-image: initial;border-top-style: solid;border-top-color: rgb(51, 51, 51);opacity: 0.25;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;> <h2 data-line="117" style="box-sizing: border-box;margin-top: 1.2em;margin-bottom: 16px;font-weight: 400;line-height: 1.2;color: rgb(0, 0, 0);font-size: 1.4641em;padding-bottom: 0.2em;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">方法四:</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 19.9118px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code><span leaf="">&nbsp;和&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 19.9118px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pageshow</span></code><span leaf="">&nbsp;事件 - 应对往返缓存(bfcache)</span></h2> <p data-line="119" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">现代浏览器(尤其是移动端)引入了“往返缓存”(Back-Forward Cache, bfcache)。当用户导航到其他页面后,如果点击“后退”按钮,浏览器可能会直接从缓存中恢复上一个页面,而不是重新加载它。在这种情况下,</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;事件可能根本不会触发。</span></p> <p data-line="121" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code><span leaf="">&nbsp;事件则可以更好地处理这种情况。</span></p> <p data-line="123" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">核心概念:</span></strong></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code><span leaf="">&nbsp;事件</span></strong><span leaf="">:在用户导航离开页面时触发,无论页面是否被存入 bfcache。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">event.persisted</span></code></strong><span leaf="">:</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code><span leaf="">&nbsp;事件对象的一个属性。如果页面被存入 bfcache,它为&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">true</span></code><span leaf="">;否则为&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">false</span></code><span leaf="">。</span></span></li> </ul> <p data-line="127" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">代码示例:</span></strong></p> <pre style="box-sizing: border-box;font-family: SFMono-Regular, Menlo, Monaco, Consolas, " liberation mono, courier new, monospace;font-size: 0.875em;display: block;margin-top: 0px;margin-bottom: 1rem;overflow: auto;color: rgb(51, 51, 51);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><code style="box-sizing: border-box;font-family: " fira code, menlo, consolas, source code pro, monospace;font-size: 14px;color: rgb(51, 51, 51);overflow-wrap: break-word;padding: 0.5em;margin: 0px;background: rgb(248, 248, 248);border-radius: 3px;word-break: normal;display: block;overflow-x: auto;><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">window</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">addEventListener</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'pagehide'</span></span><span leaf="">,</span><span style="box-sizing: border-box;"><span leaf="">&nbsp;(</span><span style="box-sizing: border-box;"><span leaf="">event</span></span><span leaf="">) =&gt;</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;color: rgb(51, 51, 51);font-weight: bold;"><span leaf="">&nbsp;if</span></span><span leaf="">&nbsp;(event.</span><span style="box-sizing: border-box;"><span leaf="">persisted</span></span><span leaf="">) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">&nbsp;console</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">log</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'页面正在进入 bfcache'</span></span><span leaf="">);</span><span leaf=""><br></span><span leaf="">&nbsp; }</span><span style="box-sizing: border-box;color: rgb(51, 51, 51);font-weight: bold;"><span leaf="">&nbsp;else</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">&nbsp;console</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">log</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'页面正在被正常卸载'</span></span><span leaf="">);</span><span leaf=""><br></span><span leaf="">&nbsp; }</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 153, 136);font-style: italic;"><span leaf="">&nbsp;// 无论哪种情况,这里都是发送 Beacon 的好时机</span></span><span leaf=""><br></span><span leaf="">&nbsp; navigator.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">sendBeacon</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'/log'</span></span><span leaf="">,</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">&nbsp;getAnalyticsData</span></span><span leaf="">());</span><span leaf=""><br></span><span leaf="">});</span><span leaf=""><br></span></code></pre> <p data-line="140" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code><span leaf="">&nbsp;比&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;更可靠,特别是在移动设备上。因此,推荐使用&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code><span leaf="">&nbsp;来代替&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">。</span></p> <h3 data-line="142" style="box-sizing: border-box;margin-top: 1.2em;margin-bottom: 16px;font-weight: 500;line-height: 1.2;color: rgb(0, 0, 0);font-size: 1.331em;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">最终建议</span></h3> <ol style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">对于“可见性”判断</span></strong><span leaf="">:优先使用&nbsp;</span><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">Page Visibility API</span></strong><span leaf="">。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">对于“离开时上报数据”</span></strong><span leaf="">:使用&nbsp;</span><strong style="box-sizing: border-box;font-weight: bolder;"><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">navigator.sendBeacon()</span></code></strong><span leaf="">,并将其放在&nbsp;</span><strong style="box-sizing: border-box;font-weight: bolder;"><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code></strong><span leaf="">&nbsp;事件监听器中,以获得最佳的兼容性和可靠性。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">对于“防止数据丢失”</span></strong><span leaf="">:仅在必要时使用&nbsp;</span><strong style="box-sizing: border-box;font-weight: bolder;"><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">beforeunload</span></code></strong><span leaf="">,因为它会中断用户操作。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">避免使用&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code></strong><span leaf="">:除非我们只需要执行一些非常简单的同步代码,否则尽量避免使用它,尤其不要在其中包含异步网络请求。</span></span></li> </ol> <p data-line="149" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">通过组合运用这些现代 API,我们不仅能准确地判断用户的行为,还能在不牺牲性能和可靠性的前提下,打造出更智能、更友好的用户体验。</span></p> <section class="mp_profile_iframe_wrp" nodeleaf=""> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-nickname="JavaScript" data-alias="FedJavaScript" data-from="0" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/btsCOHx9LAO55RFZ2rpHxp8JCdibf2zroiae9jOtwgicS0DIZM6II8CkDDY1icAQ2QakuFr6pkRJgIIdyicDM4FRic2w/0?wx_fmt=png" data-signature="为 JavaScript 爱好人员提供:Web 前端相关技术教程、JavaScript、Node.js、Deno、Vue.js、React、Angular、HTML5、CSS3 等一系列教程和经验分享" data-id="MzAwNjI5MTYyMw==" data-is_biz_ban="0" data-service_type="1" data-verify_status="0"></mp-common-profile> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

Go 隐身术:用 Garble 混淆你的代码

作者:微信小助手

<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 10px;padding-right: 10px;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;font-family: Optima, PingFangSC-regular, serif;font-size: 16px;color: rgb(0, 0, 0);line-height: 1.5em;word-spacing: 0em;letter-spacing: 0em;word-break: break-word;overflow-wrap: break-word;text-align: left;" data-pm-slice="0 0 []"> <section class="mp_profile_iframe_wrp" nodeleaf=""> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-nickname="令飞编程" data-alias="lingfeicode" data-from="0" data-headimg="http://mmbiz.qpic.cn/sz_mmbiz_png/icvNBbCQaw3lF8PebkLfZKGAIQ3wVDpefdaKdKibzK66gltnRYjLbVIuF5WOwuRNC7ribicZbaM2vWWEleicjDibGMRA/0?wx_fmt=png" data-signature="分享 Go、云原生、AI Infra 相关的技术栈及编程实战" data-id="Mzk0MTY1NDczMA==" data-is_biz_ban="0" data-service_type="1" data-verify_status="0"></mp-common-profile> </section> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">在项目开发中,经常会有需求:需要对外提供一个工具/服务,但我们不希望对方通过提供的文件,反推出实现源码。这时候,我们就需要对代码进行混淆。本文介绍如何使用 Garble 来混淆你的代码。</span></p> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span style="color: rgb(150, 84, 181);font-weight: bold;"><span leaf="">Garble</span></span><sup style="line-height: 0;color: rgb(150, 84, 181);font-weight: bold;"><span leaf="">[1]</span></sup><span leaf="">&nbsp;是由 burrowers 社区开发的开源工具,它封装了 Go 编译器,为生成高度混淆的 Go 二进制提供一站式方案。它在尽量保持二进制兼容性的同时,大幅提升源码还原和逆向的难度。</span></p> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">Garble 主要功能有:</span></p> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">标识符/包路径混淆:</span></strong><span leaf="">重命名函数、变量、结构体名,剔除大部分元数据;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">字符串字面量加密:</span></strong><span leaf="">用&nbsp;</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">-literals</span></code><span leaf="">&nbsp;标志让每个字符串运行时才被解密;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">瘦身极小文件:</span></strong><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">-tiny</span></code><span leaf="">&nbsp;删除调试符号、文件名及行号,提高攻防门槛;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">可重复构建:</span></strong><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">-seed</span></code><span leaf="">&nbsp;固定种子保证同一次混淆结果可复现;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">栈追踪逆解析:</span></strong><span leaf="">搭配已知 seed 用&nbsp;</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">garble reverse</span></code><span leaf="">&nbsp;还原混淆栈符号。</span> </section></li> </ul> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">安装 Garble</span></span><span style="display: none;"></span></h2> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span leaf="">$ go install github.com/burrowers/garble@latest</span><br></code></pre> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">混淆一个简单程序</span></span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">下面是一个示例代码:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 文件:main.go</span></span><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">package</span></span><span leaf="">&nbsp;main</span><br><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">import</span></span><span leaf="">&nbsp;</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"fmt"</span></span><br><br><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">func</span></span><span leaf="">&nbsp;</span><span style="color: #61aeee;line-height: 26px;"><span leaf="">main</span></span><span style="line-height: 26px;"><span leaf="">()</span></span></span><span leaf="">&nbsp;{</span><br><span leaf="">&nbsp; &nbsp; secret :=&nbsp;</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"Hello, Obfuscation!"</span></span><br><span leaf="">&nbsp; &nbsp; fmt.Println(process(secret))</span><br><span leaf="">}</span><br><br><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">func</span></span><span leaf="">&nbsp;</span><span style="color: #61aeee;line-height: 26px;"><span leaf="">process</span></span><span style="line-height: 26px;"><span leaf="">(s&nbsp;</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">string</span></span><span leaf="">)</span></span><span leaf="">&nbsp;</span><span style="color: #61aeee;line-height: 26px;"><span leaf="">string</span></span></span><span leaf="">&nbsp;{</span><br><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">return</span></span><span leaf="">&nbsp;s +&nbsp;</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"-processed"</span></span><br><span leaf="">}</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">正常构建:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span leaf="">$ go build -o normal_app main.go</span><br><span leaf="">$ strings normal_app | grep process</span><br><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf=""># &gt;&gt; process</span></span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">现在使用 Garble 进行混淆:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span leaf="">$ garble build -o garbled_app main.go</span><br><span leaf="">$ strings garbled_app | grep process</span><br><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf=""># &gt;&gt; no "process" found</span></span><br></code></pre> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">字面量加密(字符串不可见)</span></span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">加密每个字符串字面量:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span leaf="">$ garble -literals build -o garbled_lit main.go</span><br><span leaf="">$ strings garbled_lit | grep Hello</span><br><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf=""># &gt;&gt; (nothing – strings scrambled at runtime)</span></span><br></code></pre> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">确定性构建与逆向支持</span></span><span style="display: none;"></span></h2> <ol style="list-style-type: decimal;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">确定性混淆</span></strong> </section></li> </ol> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">修改 main.go 文件,内容如下:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">package</span></span><span leaf="">&nbsp;main</span><br><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">import</span></span><span leaf="">&nbsp;</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"fmt"</span></span><br><br><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">func</span></span><span leaf="">&nbsp;</span><span style="color: #61aeee;line-height: 26px;"><span leaf="">main</span></span><span style="line-height: 26px;"><span leaf="">()</span></span></span><span leaf="">&nbsp;{</span><br><span leaf="">&nbsp; &nbsp; secret :=&nbsp;</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"Hello, Obfuscation!"</span></span><br><span leaf="">&nbsp; &nbsp; fmt.Println(process(secret))</span><br><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">panic</span></span><span leaf="">(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"panic me"</span></span><span leaf="">)</span><br><span leaf="">}</span><br><br><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">func</span></span><span leaf="">&nbsp;</span><span style="color: #61aeee;line-height: 26px;"><span leaf="">process</span></span><span style="line-height: 26px;"><span leaf="">(s&nbsp;</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">string</span></span><span leaf="">)</span></span><span leaf="">&nbsp;</span><span style="color: #61aeee;line-height: 26px;"><span leaf="">string</span></span></span><span leaf="">&nbsp;{</span><br><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">return</span></span><span leaf="">&nbsp;s +&nbsp;</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"-processed"</span></span><br><span leaf="">}</span><br></code></pre> <hr style="margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: solid;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(119, 48, 152);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: 1px;"> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">用固定 seed 得到唯一二进制(方便 bug 还原、定位):</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span leaf="">$ garble -seed=random build -o deterministic_app main.go</span><br><span leaf="">-seed chosen at random: 75MYDgjSJGFJT7ktvUROYw</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><font style="color:rgba(6, 8, 31, 0.88);"></font></strong></p> <ol style="list-style-type: decimal;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><font style="color:rgba(6, 8, 31, 0.88);"><span leaf="">还原栈符号</span></font></strong> </section></li> </ol> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">程序崩溃需排查时,开发者可逆解析栈符号:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span leaf="">$ ./deterministic_app &amp;&gt;panic-output.txt</span><br><span leaf="">$ garble -seed=75MYDgjSJGFJT7ktvUROYw reverse main.go panic-output.txt</span><br><span leaf="">Hello, Obfuscation!-processed</span><br><span leaf="">panic: panic me</span><br><br><span leaf="">goroutine 1 [running]:</span><br><span leaf="">main.main()</span><br><span leaf="">&nbsp;</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">command</span></span><span leaf="">-line-arguments/main.go:8 +0x7c</span><br></code></pre> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">注意事项与实验特性</span></span><span style="display: none;"></span></h2> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">导出符号</span></strong><span leaf="">(用于反射/接口)不会被混淆,需知晓;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">暂不支持 Go 插件;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">控制流混淆可用实验变量开启:</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">GARBLE_EXPERIMENTAL_CONTROLFLOW=1 garble build ...</span></code><span leaf="">;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">源码信息已清理,但某些 Go runtime 字符串依然可见。</span> </section></li> </ul> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">为什么推荐 Garble?</span></span><span style="display: none;"></span></h2> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">极大提升逆向和分析难度(难以还原函数名/算法/业务逻辑);</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">完美兼容 Go 的模块、缓存、堆栈追踪、自动化构建;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">高性能:仅较&nbsp;</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">go build</span></code><span leaf="">&nbsp;慢 1-2 倍。</span> </section></li> </ul> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">实践建议</span></span><span style="display: none;"></span></h2> <ol style="list-style-type: decimal;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">CI 集成:</span></strong><span leaf="">自动/手动构建普通+混淆版;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">**-tiny**</span></code><span leaf="">** 模式:**输出极小可执行文件;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">安全增强:</span></strong><span leaf="">结合&nbsp;</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">-ldflags="-s -w"</span></code><span leaf="">&nbsp;及&nbsp;</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">-trimpath</span></code><span leaf="">&nbsp;清理符号表和绝对路径;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">高安全需求:</span></strong><span leaf="">实验性开启控制流混淆。</span> </section></li> </ol> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: flex;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;font-weight: bold;display: block;"><span leaf="">结语</span></span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">Garble 显著增加了反编译和还原成本。然而“混淆 ≠ 绝对安全”,存在如 GoStringUngarbler 工具对抗混淆字面量、或运行时调试绕过的可能。有意对手总有机会,但 Garble 是提升安全的重要一环,适合作为开发和发布流程的“最后一道保护线”。</span></p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <span leaf=""><img class="rich_pages wxw-img" data-imgfileid="100002327" src="/upload/48d34174cc0184a40dc059a554c3d2bd.png" data-type="png" style="display: block;margin-top: 0px;margin-right: auto;margin-bottom: 0px;margin-left: auto;max-width: 100%;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"></span> </figure> <section data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;"> <span style="display: block;color: rgb(0, 0, 0);font-size: 18px;line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;"><span leaf="">参考资料</span></span> </section> <section data-tool="mdnice编辑器" style="margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;"> <span style="display: flex;font-size: 14px;line-height: 1.8em;letter-spacing: 0em;"><span style="line-height: 1.8em;letter-spacing: 0em;color: rgba(0, 0, 0, 0.6);display: inline;width: 10%;background-image: none;background-position-x: initial;background-position-y: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: initial;font-size: 80%;font-family: ptima-Regular, Optima, PingFangSC-light, PingFangTC-light, 'PingFang SC', Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;padding-top: 2px;"><span leaf="">[1]&nbsp;</span></span><p style="text-align: left;text-indent: 0em;color: rgb(0, 0, 0);font-weight: normal;display: inline;padding-top: 0px;padding-right: 0px;padding-bottom: 0px;padding-left: 0px;margin-top: 0px;margin-right: 0px;margin-bottom: 0px;margin-left: 0px;word-break: break-all;flex-basis: 0%;flex-grow: 1;font-size: 14px;line-height: 1.8em;letter-spacing: 0em;"><span leaf="">Garble:&nbsp;</span><em style="margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;color: rgb(0, 0, 0);font-weight: normal;font-style: italic;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">https://github.com/burrowers/garble</span></em></p></span> </section> </section> <section> <span leaf=""><br></span> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

前端限制用户打开浏览器控制台

作者:微信小助手

<section> <span leaf="">前端代码对于有技术能力的人来说,都是开放的。只要肯下功夫都能获取到业务逻辑代码。因此前端防护只能是增加反编译难度,例如代码混淆,或者防止打开浏览器控制台。今天讲一下目前已知的限制用户打开浏览器控制台。</span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">1、禁用F12和右键</span></span><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">(基础防护)</span></span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span leaf=""><span class="code-snippet__comment">// 禁用右键菜单</span></span></code><code><span leaf=""><span class="code-snippet__variable">document</span>.<span class="code-snippet__title">addEventListener</span>(<span class="code-snippet__string">'contextmenu'</span>,&nbsp;<span class="code-snippet__function"><span class="code-snippet__params">e</span></span><span class="code-snippet__function">&nbsp;=&gt;</span>&nbsp;e.<span class="code-snippet__title">preventDefault</span>());</span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__comment">// 禁用F12、Ctrl+Shift+I等快捷键</span></span></code><code><span leaf=""><span class="code-snippet__variable">document</span>.<span class="code-snippet__title">addEventListener</span>(<span class="code-snippet__string">'keydown'</span>,&nbsp;<span class="code-snippet__function"><span class="code-snippet__params">e</span></span><span class="code-snippet__function">&nbsp;=&gt;</span>&nbsp;{</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">if</span>&nbsp;(e.<span class="code-snippet__property">key</span>&nbsp;===&nbsp;<span class="code-snippet__string">'F12'</span>&nbsp;|| (e.<span class="code-snippet__property">ctrlKey</span>&nbsp;&amp;&amp; e.<span class="code-snippet__property">shiftKey</span>&nbsp;&amp;&amp; e.<span class="code-snippet__property">key</span>&nbsp;===&nbsp;<span class="code-snippet__string">'I'</span>)) {</span></code><code><span leaf="">&nbsp; &nbsp; e.<span class="code-snippet__title">preventDefault</span>();</span></code><code><span leaf="">&nbsp; }</span></code><code><span leaf="">});</span></code></pre> </section> <p style="margin-bottom: 24px;"><span leaf="">❌ 缺点:用户仍可通过浏览器菜单栏打开开发者工具。</span></p> <section data-pm-slice="2 2 []"> <span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">2、</span></span><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">检测窗口变化</span></span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span leaf=""><span class="code-snippet__comment">// 利用窗口大小变化检测DevTools</span></span></code><code><span leaf=""><span class="code-snippet__variable">window</span>.<span class="code-snippet__title">addEventListener</span>(<span class="code-snippet__string">'resize'</span>,&nbsp;<span class="code-snippet__function">() =&gt;</span>&nbsp;{</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">if</span>&nbsp;(<span class="code-snippet__variable">window</span>.<span class="code-snippet__property">outerWidth</span>&nbsp;-&nbsp;<span class="code-snippet__variable">window</span>.<span class="code-snippet__property">innerWidth</span>&nbsp;&gt;&nbsp;<span class="code-snippet__number">100</span>&nbsp;</span></code><code><span leaf="">&nbsp; ||&nbsp;<span class="code-snippet__variable">window</span>.<span class="code-snippet__property">outerHeight</span>&nbsp;-&nbsp;<span class="code-snippet__variable">window</span>.<span class="code-snippet__property">innerHeight</span>&nbsp;&gt;&nbsp;<span class="code-snippet__number">100</span>) {</span></code><code><span leaf="">&nbsp; &nbsp;&nbsp;<span class="code-snippet__title">alert</span>(<span class="code-snippet__string">"检测到开发者工具!"</span>);</span></code><code><span leaf="">&nbsp; &nbsp;&nbsp;<span class="code-snippet__variable">window</span>.<span class="code-snippet__title">close</span>();&nbsp;<span class="code-snippet__comment">// 尝试关闭窗口</span></span></code><code><span leaf="">&nbsp; }</span></code><code><span leaf="">});</span></code></pre> </section> <p node="[object Object]" dir="auto" style="margin-bottom: 0px;margin-top: 0px;" data-pm-slice="0 0 []"><span leaf="">❌&nbsp;</span><strong><span leaf="">缺点</span></strong><span leaf="">:</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-1"> <li><p node="[object Object]" dir="auto" style="margin-bottom: 0px;" data-pm-slice="0 0 []"><span leaf="">全屏切换时的尺寸变化可能被误判;</span></p></li> <li><p node="[object Object]" dir="auto" style="margin-bottom: 24px;" data-pm-slice="0 0 []"><span leaf="">独立打开控制台页面时无法监听到;</span></p></li> </ul> <section data-pm-slice="2 2 []"> <span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">3、</span></span><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">无限Debugger</span></span><span leaf=""><br></span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span leaf=""><span class="code-snippet__built_in">setInterval</span>(<span class="code-snippet__function">() =&gt;</span>&nbsp;{</span></code><code><span leaf="">&nbsp; (<span class="code-snippet__keyword">function</span>&nbsp;(<span class="code-snippet__params">a</span>) {</span></code><code><span leaf="">&nbsp; &nbsp;&nbsp;<span class="code-snippet__keyword">return</span>&nbsp;(<span class="code-snippet__keyword">function</span>&nbsp;(<span class="code-snippet__params">a</span>) {</span></code><code><span leaf="">&nbsp; &nbsp; &nbsp;&nbsp;<span class="code-snippet__keyword">return</span>&nbsp;<span class="code-snippet__title">Function</span>(<span class="code-snippet__string">'Function(arguments[0]+"'</span>&nbsp;+ a +&nbsp;<span class="code-snippet__string">'")()'</span>);</span></code><code><span leaf="">&nbsp; &nbsp; })(a);</span></code><code><span leaf="">&nbsp; })(<span class="code-snippet__string">"bugger"</span>)(<span class="code-snippet__string">"de"</span>,&nbsp;<span class="code-snippet__number">0</span>,&nbsp;<span class="code-snippet__number">0</span>, (<span class="code-snippet__number">0</span>,&nbsp;<span class="code-snippet__number">0</span>));</span></code><code><span leaf="">},&nbsp;<span class="code-snippet__number">1000</span>);</span></code></pre> </section> <p node="[object Object]" dir="auto" style="margin-bottom: 24px;margin-top: 0px;" data-pm-slice="2 4 []"><span leaf="">❌&nbsp;</span><strong><span leaf="">缺点</span></strong><span leaf="">:用户可禁用断点(</span><code><span leaf="">Deactivate breakpoints</span></code><span leaf="">)绕过</span></p> <section data-pm-slice="2 2 []"> <section> <span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">4、检测控制台打开并跳转/弹窗</span></span> </section> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span leaf=""><span class="code-snippet__comment">// 利用debugger检测控制台是否打开</span></span></code><code><span leaf=""><span class="code-snippet__built_in">setInterval</span>(<span class="code-snippet__function">() =&gt;</span>&nbsp;{</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">const</span>&nbsp;start =&nbsp;<span class="code-snippet__title">Date</span>.<span class="code-snippet__title">now</span>();</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">debugger</span>;</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">if</span>&nbsp;(<span class="code-snippet__title">Date</span>.<span class="code-snippet__title">now</span>() - start &gt;&nbsp;<span class="code-snippet__number">100</span>) {</span></code><code><span leaf="">&nbsp; &nbsp;&nbsp;<span class="code-snippet__title">alert</span>(<span class="code-snippet__string">"禁止调试!"</span>);</span></code><code><span leaf="">&nbsp; &nbsp;&nbsp;<span class="code-snippet__variable">window</span>.<span class="code-snippet__property">location</span>.<span class="code-snippet__property">href</span>&nbsp;=&nbsp;<span class="code-snippet__string">"about:blank"</span>;&nbsp;<span class="code-snippet__comment">// 跳转空白页</span></span></code><code><span leaf="">&nbsp; }</span></code><code><span leaf="">},&nbsp;<span class="code-snippet__number">1000</span>);</span></code></pre> </section> <p node="[object Object]" dir="auto" style="margin-bottom: 0px;margin-top: 0px;" data-pm-slice="2 2 []"><span leaf="">❌&nbsp;</span><strong><span leaf="">缺点</span></strong><span leaf="">:</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-1"> <li> <section style="margin-bottom: 24px;"> <span leaf="">用户可禁用断点(</span><code><span leaf="">Deactivate breakpoints</span></code><span leaf="">)绕过。</span> </section></li> </ul> <p node="[object Object]" dir="auto" style="margin-bottom: 0px;margin-top: 0px;" data-pm-slice="2 4 []"><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">优化</span></span></p> <p node="[object Object]" dir="auto" style="margin-bottom: 0px;margin-top: 0px;" data-pm-slice="2 4 []"><span leaf=""><br></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span leaf=""><span class="code-snippet__comment">// 利用console.table在控制台打开时耗费时间更长检测控制台是否打开</span></span></code><code><span leaf=""><span class="code-snippet__keyword">function</span>&nbsp;<span class="code-snippet__title">initData</span>() {</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">for</span>&nbsp;(</span></code><code><span leaf="">&nbsp; &nbsp;&nbsp;<span class="code-snippet__keyword">var</span>&nbsp;o = (<span class="code-snippet__keyword">function</span>&nbsp;() {</span></code><code><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="code-snippet__keyword">for</span>&nbsp;(<span class="code-snippet__keyword">var</span>&nbsp;w = {}, D =&nbsp;<span class="code-snippet__number">0</span>; D &lt;&nbsp;<span class="code-snippet__number">500</span>; D++) w[<span class="code-snippet__string">""</span>.<span class="code-snippet__title">concat</span>(D)] =&nbsp;<span class="code-snippet__string">""</span>.<span class="code-snippet__title">concat</span>(D);</span></code><code><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="code-snippet__keyword">return</span>&nbsp;w;</span></code><code><span leaf="">&nbsp; &nbsp; &nbsp; })(),i = [],c =&nbsp;<span class="code-snippet__number">0</span>;c &lt;&nbsp;<span class="code-snippet__number">50</span>;c++) i.<span class="code-snippet__title">push</span>(o);</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">return</span>&nbsp;i;</span></code><code><span leaf="">}</span></code><code><span leaf=""><span class="code-snippet__keyword">let</span>&nbsp;largeObjectArray =&nbsp;<span class="code-snippet__title">initData</span>()</span></code><code><span leaf=""><span class="code-snippet__built_in">setInterval</span>(<span class="code-snippet__function">() =&gt;</span>&nbsp;{</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">const</span>&nbsp;start =&nbsp;<span class="code-snippet__title">Date</span>.<span class="code-snippet__title">now</span>();</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__variable">console</span>.<span class="code-snippet__title">table</span>(largeObjectArray)</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">if</span>&nbsp;(<span class="code-snippet__title">Date</span>.<span class="code-snippet__title">now</span>() - start &gt;&nbsp;<span class="code-snippet__number">100</span>) {</span></code><code><span leaf="">&nbsp; &nbsp;&nbsp;<span class="code-snippet__variable">window</span>.<span class="code-snippet__property">location</span>.<span class="code-snippet__property">href</span>&nbsp;=&nbsp;<span class="code-snippet__string">"about:blank"</span>;&nbsp;<span class="code-snippet__comment">// 跳转空白页</span></span></code><code><span leaf="">&nbsp; }</span></code><code><span leaf="">},&nbsp;<span class="code-snippet__number">1000</span>);</span></code></pre> </section> <p node="[object Object]" dir="auto" style="margin-bottom: 0px;margin-top: 0px;" data-pm-slice="2 4 []"><span leaf="">❌&nbsp;</span><strong><span leaf="">缺点</span></strong><span leaf="">:</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-1"> <li> <section style="margin-bottom: 24px;"> <span leaf="">用户可重写console.table方法跳过。</span> </section></li> </ul> <section style="margin-bottom:24px;"> <span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">结语</span></span> </section> <p><span leaf="">网站安全不能只依赖前端技术,前端只能“</span><span leaf="" data-pm-slice="1 1 [" para,{tagname:p,attributes:{},namespaceuri:http: www.w3.org 1999 xhtml}]>防君子不防小人</span><span leaf="">”。有一定技术能力的用户都可以绕过前端防护,并反编译前端代码。还是得靠后端服务来确保网站的安全。</span></p> <section class="mp_profile_iframe_wrp" nodeleaf=""> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-nickname="焚心小记" data-from="0" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/yrG4X0r4SEEcn9ByGFRD28YuQaNHS9cib0D8Ercia07LJNM67cKXVwBNtQiaum0VIROqK0Cf8UgbeDPCCdClQGmMw/0?wx_fmt=png" data-signature="人生无时不在焚心,无非是文火与武火的区别罢了。给生活留下点痕迹,给自己留下点回忆。" data-id="MzA5NDc4ODA2Mg==" data-is_biz_ban="0" data-service_type="1" data-verify_status="0"></mp-common-profile> </section> <p><span leaf="">关注公众号,获取更多前端技术问题。动动小手,点个赞吧</span></p> <section style="text-align: center;" nodeleaf=""> <img class="rich_pages wxw-img" data-imgfileid="100000531" data-ratio="1.0085836909871244" src="/upload/cbb0988170d4360edf577fc54e505285.png" data-type="gif" data-w="233" type="block"> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>