12k
All articles

Web 端邮箱混淆技术

网页邮箱混淆技巧:比较HTML实体编码、JavaScript、应避免的CSS、联系表单和Cloudflare保护。

OpenReplay Team
OpenReplay Team
Web 端邮箱混淆技术

每一个公开的邮箱地址都是攻击目标。当你在 HTML 中放入一个裸露的 mailto: 链接时,自动化的爬虫程序可以迅速收集到它。本文将介绍前端开发者最实用的邮箱混淆技术——每种技术的原理、面对现代爬虫工具的有效程度,以及它们在可用性或可访问性方面的不足。

需要预先说明一个重要事项:邮箱混淆并不能保证安全。它只能减少自动化采集,无法阻止有针对性的收集。无头浏览器、AI 辅助爬虫和 OCR 工具的出现,使得几种较老的技术远不如以往可靠。我们的目标是提高采集成本,而非让发现变得不可能。

核心要点

  • 裸露的 mailto: 链接极易被爬取,会同时在 href 属性和可见的 DOM 中暴露你的地址。
  • HTML 实体编码对基于简单正则的爬虫意外地有效,但对无头浏览器毫无防御能力。
  • 基于 JavaScript 的技术(字符串拼接、转换函数、通过 SubtleCrypto 实现的 AES)显著提高了基础爬虫的门槛。
  • CSS 技巧如反转文本或 ::after 伪元素会损害可用性和可访问性——应避免使用。
  • 联系表单避免在页面 HTML 中暴露地址,但应配合蜜罐字段或注重隐私的 CAPTCHA(如 Cloudflare Turnstile)使用。
  • 多种技术分层组合可提供最佳的实际防护效果。

为什么裸露的 mailto 链接是个问题

一个未受保护的 mailto: 链接,例如:

<a href="mailto:contact@example.com">Email us</a>

极易被爬取。基于正则的机器人能瞬间发现它。它在两个地方暴露了你的地址:href 属性,以及——如果你将地址显示为链接文本——可见的 DOM。要想有效减少垃圾邮件,这两处都需要保护。

HTML 实体编码

将邮箱地址中的每个字符替换为其对应的 HTML 实体,是最古老的混淆技术之一:

<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#99;&#111;&#110;&#116;&#97;&#99;&#116;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;">Email us</a>

浏览器会正确解码并渲染出可用的 mailto 链接。Spencer Mortensen 的蜜罐测试发现,这种方式拦截了高比例针对可点击链接的爬虫——考虑到服务端库可以轻松解码实体,这种效果令人意外。它之所以有效,是因为大多数爬虫并不复杂。然而,它对无头浏览器或任何处理渲染后 DOM(而非原始 HTML)的爬虫毫无防御作用。

可用性: 无影响。可访问性: 完全兼容。可维护性: 手写繁琐——请使用生成器。

基于 JavaScript 的混淆

JavaScript 技术将邮箱地址完全从静态 HTML 中移除,这显著提高了基础爬虫的门槛。

字符串拼接 将地址拆分到多个字符串片段中,在运行时进行组装。完整地址永远不会出现在 HTML 源码中,只在执行后存在于内存里。

<a id="contact-link" href="#">Email us</a>
<script>
  const user = "contact";
  const domain = "example.com";
  const link = document.getElementById("contact-link");
  link.href = "mailto:" + user + "@" + domain;
  link.textContent = user + "@" + domain;
</script>

自定义转换函数 更进一步。HTML 源码中包含无意义的占位文本,只有在页面在真实浏览器环境中渲染时,一个小型 JS 函数才会将其转换为有效地址。这是 mailto 链接防垃圾邮件最有效的方法之一,因为它需要完整的 JavaScript 执行才能还原地址。

AES 加密 使用浏览器原生的 SubtleCrypto API,在构建时加密地址,并在客户端解密。由于 SubtleCrypto 只能在安全上下文中运行,这要求使用 HTTPS——而你本就应该已经在使用。根据 Can I Use 的数据,现代浏览器已广泛支持该 API。

重要局限: 这些技术都无法阻止 Puppeteer 或 Playwright 等无头浏览器,它们能完整执行 JavaScript。但它们能阻止大多数仍然基于正则、只处理原始 HTML 的爬虫。

可用性: 实现得当时极佳。可访问性: 取决于实现——确保渲染出的链接可通过键盘导航且对屏幕阅读器友好。可维护性: 中等。

应避免的 CSS 技术

一些 CSS 方法——反转文本方向、屏幕外定位或 ::after 伪元素——看似巧妙,但严重破坏可用性。通过 ::after 渲染的文本无法被选中或复制。反转文本即便能复制也会让用户困惑。这些技术也无法抵御任何同时解析 CSS 和 HTML 的爬虫。请避免使用。

联系表单作为替代方案

用联系表单替代公开的邮箱地址,可以完全避免在页面 HTML 中暴露地址。代价是可用性:许多用户更倾向于直接发邮件,而较长的表单会降低转化率。

如果你使用联系表单,请保护好它。机器人可以自动提交表单。添加一个蜜罐字段——一个真实用户从不填写但机器人通常会填写的隐藏输入框——作为轻量级、可访问的第一层防护。对于流量较大的表单,Cloudflare Turnstile 提供了一种注重隐私的 CAPTCHA 替代方案,比 reCAPTCHA v2 的摩擦更小。

可访问性提示: 基于图像的 CAPTCHA 对视障用户造成实质性障碍。务必提供音频替代方案,或选择不依赖纯视觉挑战的 CAPTCHA 方案。WCAG 2.2 指南是一个很好的参考依据。

Cloudflare 邮箱地址混淆

如果你的网站在 Cloudflare 后端运行,其内置的邮箱地址混淆功能值得启用。Cloudflare 会在边缘节点重写你 HTML 中的邮箱地址,在页面到达客户端之前完成,然后注入一个延迟加载的小型解码脚本(email-decode.min.js),在浏览器中将其还原。该脚本以 defer 方式加载,因此不会阻塞渲染。

这种方法对用户实际上是透明的,且无需对代码库做任何修改。主要限制在于它不适用于 <script><noscript><textarea><head> 标签内部,并且如果你的页面带有 Cache-Control: no-transform 响应头,它也无法工作。

通过分层组合提升防护覆盖

没有任何单一技术能够独立胜任。对大多数网站而言,一个实用的组合是:

  • 使用 JavaScript 转换或 AES 加密 保护 mailto 链接的 href 属性。
  • 对任何可见的地址文本应用 HTML 实体编码 作为辅助层。
  • 添加带有 蜜罐字段的联系表单 作为替代联系方式。
  • 如果你已在 Cloudflare 网络上,启用 Cloudflare 邮箱混淆

这种分层方法同时覆盖了链接属性和可见文本,弥合了仅读取原始 HTML 的爬虫与执行 JavaScript 的爬虫之间的差距。

结论

邮箱混淆能切实减少自动化采集。蜜罐数据一致表明,即便是基础技术也能拦截大量爬虫,因为许多采集者仍然不够先进。但混淆并不能替代优秀的垃圾邮件过滤器,也无法阻止有决心的、针对性的收集。

实施一两种可靠的技术,在合理之处分层使用,然后继续前进。节省下来的时间最好用在别处。

常见问题

HTML 实体编码在 2026 年仍然有效吗?

是的,但仅对不复杂的爬虫有效。蜜罐测试表明,它仍能阻挡许多基于正则的爬虫,因为它们读取原始 HTML 时不会解码实体。然而,任何解析渲染后 DOM 的爬虫(包括 Puppeteer 等无头浏览器)都能看到解码后的地址。请将其作为更广泛策略中的一层使用,而非独立防御。

无头浏览器能绕过基于 JavaScript 的邮箱混淆吗?

可以。Puppeteer 和 Playwright 等无头浏览器能完整执行 JavaScript,因此任何依赖运行时解码的技术——包括字符串拼接、转换函数和 AES 解密——都能被它们击败。基于 JS 的混淆的价值在于阻止数量更庞大的基于正则的爬虫,后者仍占据自动化采集流量的很大比例。

联系表单比混淆的 mailto 链接更好吗?

这取决于你的目标。联系表单避免了在页面 HTML 中暴露邮箱地址,对基础采集提供了更强的保护。但表单会降低转化率,且许多用户更倾向于直接发邮件。一种平衡的做法是同时提供两者:为愿意使用的用户提供混淆的 mailto 链接,并配以带蜜罐字段的受保护联系表单作为后备。

Cloudflare 邮箱混淆会影响 SEO 或可访问性吗?

通常不会有实质性影响,但仍应在真实页面和辅助技术上进行测试。解码脚本会在页面加载后于客户端还原地址,之后键盘导航通常可以正常工作。搜索引擎一般不将邮箱地址视为排名信号,因此实际的 SEO 影响很小。只需确保你的页面没有携带 Cache-Control no-transform 响应头即可。

DevTools for the frontend

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.