如何在 HTML 中实现 CAPTCHA:一份简单的开发者指南

为你的 HTML 表单添加 CAPTCHA,是防御机器人、垃圾提交和自动化滥用最有效的第一道防线之一。无论你是在保护登录页面、联系表单还是结账流程,选择合适的 CAPTCHA——以及正确的实现方式——都能带来显著的不同。
本指南将逐步讲解如何把 captcha html 代码添加到你的项目中,涵盖四种常见方案: reCAPTCHA v2(复选框版和隐形版)、 Cloudflare Turnstile、 Prosopo Procaptcha 和 Altcha。对于每一种方案,你都将获得完整说明、可运行的 HTML 代码示例,以及关于后端验证、本地测试和故障排查的指导。
开始之前你需要准备什么
每种 CAPTCHA 解决方案通常都围绕同一个核心概念运行:你向提供商注册自己的网站,获得一对 captcha key(公开的 site key 和私密的 secret key),然后使用这些密钥嵌入小部件并验证响应。
在你写下任何一行 HTML 之前,先在以下位置注册各个提供商:
在注册过程中,系统会要求你提供你的 域名。对于本地开发,请将 localhost 添加到允许的域名列表中(测试部分会进一步说明)。
reCAPTCHA v2 复选框版——分步说明
经典的复选框(“I'm not a robot”)是最广为人知的 captcha html 小部件。它会显示一个可见的复选框,并在需要时显示可视化图片挑战。
第 1 步:注册并获取你的 captcha key
前往 google.com/recaptcha/admin,然后选择 reCAPTCHA v2 → “I'm not a robot” Checkbox。添加你的域名(包括用于本地测试的 localhost),然后保存。你会获得一个 Site Key 和一个 Secret Key。
第 2 步:添加 reCAPTCHA API 脚本
将以下 <script> 标签放入你的 HTML <head> 中,或放在闭合的 </body> 标签之前:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>async 和 defer 属性可确保脚本在不阻塞页面渲染的情况下加载。
第 3 步:将小部件 div 添加到表单中
将这个 <div> 元素放在表单内、提交按钮之前。把 YOUR_SITE_KEY 替换为你获得的 site key。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Contact Form</title>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<form action="/submit" method="POST">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<label for="message">Message:</label>
<textarea id="message" name="message" required></textarea>
<!-- reCAPTCHA v2 复选框小部件 -->
<div class="g-recaptcha" data-sitekey="YOUR_SITE_KEY"></div>
<button type="submit">Send</button>
</form>
</body>
</html>第 4 步:提交时会发生什么
当用户完成挑战并提交表单时,Google 的脚本会自动将一个名为 g-recaptcha-response 的隐藏输入字段附加到你的表单数据中。你的后端读取这个令牌,并将其与 secret key 一起发送到 Google 的验证 API。
reCAPTCHA v2 隐形版——分步说明
Invisible reCAPTCHA 会完全移除可见的复选框。相反,它会在后台进行风险分析,只有在检测到可疑行为时才会触发可视化挑战——这会为大多数用户带来更顺畅的用户体验。
第 1 步:使用正确的类型进行注册
在 Google reCAPTCHA 管理控制台中,选择 reCAPTCHA v2 → Invisible reCAPTCHA badge。这会生成一个与复选框版本 不同 的 site key——不要在不同类型之间复用密钥。
第 2 步:加载 API 脚本
使用与复选框版本相同的脚本标签:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>第 3 步:将 CAPTCHA 附加到提交按钮
你不再使用单独的 <div>,而是将 CAPTCHA 属性直接应用到提交 <button> 上,并指定一个在挑战完成后运行的 JavaScript 回调。
定义一个回调函数,在验证通过后以编程方式提交表单。
完整 HTML 表单示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sign Up</title>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<form id="signup-form" action="/signup" method="POST">
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
<!-- 隐形 reCAPTCHA:附加到按钮上 -->
<button
class="g-recaptcha"
data-sitekey="YOUR_SITE_KEY"
data-callback="onSubmit"
data-size="invisible"
type="submit">
Create Account
</button>
</form>
<script>
function onSubmit(token) {
document.getElementById("signup-form").submit();
}
</script>
</body>
</html>当按钮被点击时,reCAPTCHA 会执行后台分析,使用响应令牌调用 onSubmit(token),而你的回调函数会提交表单。该令牌会作为 g-recaptcha-response 包含在 POST 请求体中。
Cloudflare Turnstile——分步说明
Cloudflare Turnstile 是一种以隐私为先的 CAPTCHA 替代方案,不会跟踪用户、设置用于画像分析的 Cookie,也不会显示图片谜题。它提供三种小部件模式:
- 托管型(Managed):小部件会根据浏览器信号决定是否显示挑战)
- 非交互式(Non-interactive): 对大多数访客而言,无需交互即可通过
- 隐形(Invisible): 完全在后台运行
第 1 步:在 Cloudflare 控制台中创建一个小部件
登录你的 Cloudflare 账户,进入 Application security → Turnstile,点击 Add widget,输入你的域名,并选择一种小部件类型。复制 Site Key,并记下你的 Secret Key。
第 2 步:添加 Turnstile 脚本
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>第 3 步:将小部件 div 添加到表单中
<div class="cf-turnstile" data-sitekey="YOUR_SITE_KEY"></div>Turnstile 会自动向表单中注入一个名为 cf-turnstile-response 的隐藏输入字段。对于标准表单提交,不需要额外的 JavaScript。
完整 HTML 表单示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
</head>
<body>
<form action="/login" method="POST">
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
<!-- Cloudflare Turnstile 小部件 -->
<div class="cf-turnstile" data-sitekey="YOUR_SITE_KEY"></div>
<button type="submit">Log In</button>
</form>
</body>
</html>Turnstile 的托管型模式会根据浏览器信号决定——是显示交互,还是静默通过。对于测试,Cloudflare 提供了专用的 dummy site keys(测试部分会介绍)。
Prosopo Procaptcha——分步说明
Prosopo Procaptcha 是一种原生 Web3、注重隐私的 CAPTCHA,旨在作为 reCAPTCHA 的直接即插即用替代方案。它不依赖 Google 的基础设施,并将用户隐私作为核心设计原则。
第 1 步:从 Prosopo 获取你的 captcha key
在 prosopo.io 注册并创建一个新站点,以获取你的 Site Key。
第 2 步:加载 Procaptcha bundle
添加 Procaptcha 脚本:
<script src="https://js.prosopo.io/js/procaptcha.bundle.js" async defer></script>第 3 步:将小部件添加到表单中
放置一个带有 procaptcha 类名的 <div>,并将你的 site key 设为 data-sitekey 属性。
完整 HTML 表单示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Register</title>
<script type="module" src="https://js.prosopo.io/js/procaptcha.bundle.js" async defer></script>
</head>
<body>
<form action="/register" method="POST">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<!-- Prosopo Procaptcha 小部件 -->
<div class="procaptcha" data-sitekey="YOUR_SITE_KEY"></div>
<button type="submit">Register</button>
</form>
</body>
</html>第 4 步:令牌提交
在表单提交时,Procaptcha 会向你的表单中注入一个名为 procaptcha-response 的隐藏字段。在后端,将这个令牌与你的 secret key 一起传递给 Prosopo 的验证 API。
Altcha——分步说明
Altcha 是一个完全开源、自托管的 CAPTCHA,它使用 proof-of-work 机制——用户的浏览器执行一个小型计算任务,而不是解答可视化谜题。它不会收集用户数据,不会设置跟踪 Cookie,并且完全符合 GDPR。由于它是自托管的,因此不存在第三方依赖。
第 1 步:加载 Altcha 小部件
无需注册。加载这个自定义元素脚本:
<script async defer type="module"
src="https://cdn.jsdelivr.net/gh/altcha-org/altcha/dist/altcha.min.js">
</script>第 2 步:设置 challenge 端点
Altcha 需要一个服务器端端点来生成加密 challenge(使用由你定义的 HMAC secret key)。该端点会在提交前被小部件调用,以获取一个新的 challenge。你所使用框架的 Altcha 服务器库会处理这部分逻辑。端点 URL 通过 challengeurl 属性传递给小部件。
第 3 步:将小部件添加到你的 HTML 表单中
完整 HTML 表单示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Feedback</title>
<script async defer type="module"
src="https://cdn.jsdelivr.net/gh/altcha-org/altcha/dist/altcha.min.js">
</script>
</head>
<body>
<form action="/feedback" method="POST">
<label for="feedback">Your feedback:</label>
<textarea id="feedback" name="feedback" required></textarea>
<!-- Altcha 小部件——指向你自己的 challenge 端点 -->
<altcha-widget challengeurl="/api/altcha-challenge"></altcha-widget>
<button type="submit">Submit</button>
</form>
</body>
</html>第 4 步:令牌提交
在 proof-of-work 完成后,Altcha 会用一个经过 base64 编码的负载填充名为 altcha 的隐藏输入字段。你的后端会根据你的 HMAC secret 验证该负载——无需调用外部 API。
后端验证——其工作原理
无论你使用哪一种 CAPTCHA,服务端验证模式都是相同的:
- 从 POST 请求体中提取令牌,使用各提供商对应的字段名(g-recaptcha-response、 cf-turnstile-response、 procaptcha-response 或 altcha)。
- 将令牌发送到提供商的验证端点——发送一个 POST 请求,其中包含你的 secret key 和用户的令牌(对于 reCAPTCHA,还可以附带用户的 IP 地址)。
- 解析 JSON 响应——提供商会在响应中返回成功/失败指示。reCAPTCHA 和 Turnstile 使用 success: true/false 字段;Prosopo 使用 verified: true/false;Altcha 则依据你的 HMAC secret 在本地完成验证。有些提供商还会返回 hostname 和 challenge 时间戳。
- 接受或拒绝提交——如果验证失败,就向用户返回错误,不要处理表单数据;如果验证通过,则正常继续。
各提供商的验证端点:
- reCAPTCHA v2: [https://www.google.com/recaptcha/api/siteverify](https://www.google.com/recaptcha/api/siteverify)
- Cloudflare Turnstile: [https://challenges.cloudflare.com/turnstile/v0/siteverify](https://challenges.cloudflare.com/turnstile/v0/siteverify)
- Prosopo: [https://api.prosopo.io/siteverify](https://api.prosopo.io/siteverify)
- Altcha: 本地验证——根据你自己的 HMAC secret 进行验证,无需外部调用
⚠️ 绝不要在后端验证中使用你的 site key——始终使用 secret key。把两者混淆是最常见的集成错误之一。
在本地服务器上测试你的 CAPTCHA HTML
由于大多数提供商都会验证域名,因此在本地测试 CAPTCHA 需要额外做几个步骤。
- reCAPTCHA v2: 在 Google reCAPTCHA 管理控制台的允许域名列表中添加 localhost。该小部件将在 http://localhost 上正常渲染并运行。
- Cloudflare Turnstile: 使用 Cloudflare 官方提供的 测试 site key。其中, 1x00000000000000000000AA 始终返回通过结果; 2x00000000000000000000AB 始终返回失败。你还可以在后端将通过用的 site key(1x00000000000000000000AA)与 secret key 3x0000000000000000000000000000000AA 搭配使用,以模拟 “timeout-or-duplicate” 错误。部署前,请将所有测试 key 替换为真实的生产 key。
- Prosopo Procaptcha: localhost 在开发期间开箱即用——无需额外配置。
- Altcha: 由于它是自托管的, localhost 可原生工作。只要确保你的 challenge 端点也在本地运行即可。
使用浏览器的 DevTools → Network 选项卡 来确认 CAPTCHA API 脚本已加载(HTTP 200),并确认你的表单 POST 中包含预期的令牌字段。
排查常见问题
CAPTCHA 小部件未渲染
- 仔细检查 site key 是否与你注册的 CAPTCHA 类型匹配(复选框类型的 key 不能用于隐形版,反之亦然)。
- 确认 API <script> 标签存在,并且能在 DevTools 中正常加载,不会出现 404 或 CORS 错误。
- 确保你注册时填写的域名与你当前提供服务的域名一致,包括是否带有 www.。
表单 POST 中缺少令牌
- 隐藏输入字段只有在 challenge 完成后才会被注入。如果用户在它准备好之前就提交,就不会发送任何令牌。
- 对于 Invisible reCAPTCHA,请确保 onSubmit 回调是在令牌可用之后 才触发 form.submit(),而不是之前。
- 对于 Altcha,请确认你的 challenge 端点可以访问,并且返回的是有效的 challenge。
后端验证返回失败响应
- 确认你发送到验证端点的是 secret key(而不是 site key)。
- 令牌通常都是 一次性使用 的——如果你在测试中重复重试同一个 POST,请每次都生成一个新的令牌。
- 检查时钟偏差:某些提供商(尤其是 Altcha)会拒绝过旧的 challenge。
“Invalid domain” 或 sitekey mismatch 错误
- 在 localhost 上,请确保允许域名列表中填写的是 localhost(而不是 127.0.0.1)。
- 对于 Turnstile,在本地开发期间请切换为测试 site key。
小部件被隐藏或与其他元素重叠
- CAPTCHA 小部件会在 iframe 中渲染,并带有固定的 z-index。如果另一个元素(模态层、粘性页眉等)具有更高的 z-index,就可能遮挡该小部件。
- 为父容器显式设置 z-index,或者检查祖先元素上是否设置了 overflow: hidden,从而裁剪掉了 iframe。
无障碍说明: 本指南中的四个提供商都提供了无障碍替代方式。reCAPTCHA 和 Turnstile 提供音频 challenge;Prosopo 和 Altcha 默认设计为尽量减少用户操作阻碍,从而降低对可视化谜题的依赖。
使用 CapMonster Cloud 自动化与测试 CAPTCHA 求解
当你的 CAPTCHA 实现上线后,你可能需要以编程方式对其进行测试——用于 QA 流水线、集成测试或自动化监控。每次测试运行时都手动完成 CAPTCHA,不具备现实可行性,尤其是在大规模场景下。
CapMonster Cloud 是一项由 AI 驱动的自动化 CAPTCHA 求解服务,支持本指南涵盖的全部四种 CAPTCHA 类型:reCAPTCHA v2(复选框版和隐形版)、Cloudflare Turnstile、Prosopo Procaptcha 和 Altcha。它通过一个简单的 API 工作:你发送一个任务,其中包含目标页面 URL 和 site key,该服务就会返回一个已求解的令牌,可直接注入到你的表单中。
它如何融入开发者工作流:
- 自动化集成测试: 在 CI/CD 流水线中对受 CAPTCHA 保护的表单运行端到端测试,无需人工交互。
- QA 验证: 确认你的后端在不同条件下能够正确验证并拒绝令牌。
- 作为已获授权工作流一部分、需要与受 CAPTCHA 保护页面交互的数据采集流水线。
CapMonster Cloud 兼容广泛使用的 API 接口,这意味着它只需极少配置即可集成到许多现有自动化框架中。你提交一个包含页面 URL 和 site key 的任务,轮询获取结果,然后接收令牌——再将其作为表单中相应隐藏字段的值注入即可。
结论
实现一个 captcha html 方案并不需要复杂的基础设施——只需要一个脚本标签、一个小部件元素、正确的 captcha key 对,以及服务端令牌校验。本指南中的每个选项都有各自的优势:reCAPTCHA v2 久经考验并被广泛信任;Turnstile 几乎不会打断用户操作且更注重隐私;Prosopo 提供了一个不依赖 Google 的原生 Web3 替代方案;而 Altcha 则通过自托管、开源基础设施让你获得完全控制权。
准备开始了吗? 选择最符合你在隐私、用户体验和基础设施方面需求的 CAPTCHA,注册你的 site key,然后使用上面的代码示例,在几分钟内把它接入到你的表单中。如果你需要在受保护表单上自动化测试或执行 QA, CapMonster Cloud 支持全部四个提供商,并可直接集成到你现有的流水线中。






