外观
迁移指南
从 reCAPTCHA / hCaptcha / Turnstile 迁移到 Capcat 只有两处改动:
- 前端:换
<script>地址,把验证容器换成<cap-widget>; - 服务端:换 siteverify 的 URL、secret,以及读取的表单字段名。
siteverify 请求同时兼容 JSON 与表单编码(secret=…&response=…),原有的 reCAPTCHA / hCaptcha 客户端代码通常只改 URL 和 secret 就能用。
开始前先在控制台创建站点,拿到你的 site key 和 secret。
对照总览
| reCAPTCHA v2 | hCaptcha | Turnstile | Capcat | |
|---|---|---|---|---|
| 脚本地址 | www.google.com/recaptcha/api.js | js.hcaptcha.com/1/api.js | challenges.cloudflare.com/turnstile/v0/api.js | capcat.ai/widget/cap.js |
| 前端标签 | <div class="g-recaptcha"> | <div class="h-captcha"> | <div class="cf-turnstile"> | <cap-widget> |
| 表单 token 字段 | g-recaptcha-response | h-captcha-response | cf-turnstile-response | cap-token |
| siteverify 地址 | www.google.com/recaptcha/api/siteverify | api.hcaptcha.com/siteverify | challenges.cloudflare.com/turnstile/v0/siteverify | api.capcat.ai/<site-key>/siteverify |
| 通过判定 | success: true | success: true | success: true | success: true |
从 reCAPTCHA 迁移
前端
html
<!-- 之前 -->
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<form action="/submit" method="POST">
<div class="g-recaptcha" data-sitekey="<recaptcha-site-key>"></div>
<button type="submit">提交</button>
</form>
<!-- 之后 -->
<script src="https://capcat.ai/widget/cap.js"></script>
<form action="/submit" method="POST">
<cap-widget data-cap-api-endpoint="https://api.capcat.ai/<site-key>/"></cap-widget>
<button type="submit">提交</button>
</form><cap-widget> 放在 <form> 内会自动注入隐藏的 cap-token 字段随表单提交,与 g-recaptcha-response 的机制一致;不需要 onload 回调或 grecaptcha.render()。
服务端
把 siteverify 的 URL 换成 Capcat、secret 换成控制台生成的 secret、读取的字段从 g-recaptcha-response 换成 cap-token:
js
// 之前
const token = req.body["g-recaptcha-response"];
const r = await fetch("https://www.google.com/recaptcha/api/siteverify", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({ secret: RECAPTCHA_SECRET, response: token }),
});
// 之后 —— 表单编码原样可用,只改了 URL、secret 与字段名
const token = req.body["cap-token"];
const r = await fetch("https://api.capcat.ai/<site-key>/siteverify", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({ secret: CAPCAT_SECRET, response: token }),
});
const { success } = await r.json();remoteip 等多余参数会被忽略,不必删除。
用的是 reCAPTCHA v3?
v3 的「无感评分」没有直接对应物——Capcat 不给用户打分,验证结果只有通过 / 不通过。但 v3 的典型场景(表单防刷、接口防滥用)可以直接用 Capcat 替代:工作量证明在浏览器后台静默完成,用户只需点一次复选框,没有图形拼图。服务端不再有 score 与 action 字段,把阈值判断改为检查 success 即可。
从 hCaptcha 迁移
前端
html
<!-- 之前 -->
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
<div class="h-captcha" data-sitekey="<hcaptcha-site-key>"></div>
<!-- 之后 -->
<script src="https://capcat.ai/widget/cap.js"></script>
<cap-widget data-cap-api-endpoint="https://api.capcat.ai/<site-key>/"></cap-widget>服务端
hCaptcha 的 siteverify 与 reCAPTCHA 同构:URL 换成 https://api.capcat.ai/<site-key>/siteverify,secret 换成 Capcat 的,token 字段从 h-captcha-response 换成 cap-token。表单编码与 JSON 都接受,sitekey / remoteip 参数忽略即可。
py
# 之前
requests.post("https://api.hcaptcha.com/siteverify",
data={"secret": HCAPTCHA_SECRET, "response": request.form["h-captcha-response"]})
# 之后
requests.post("https://api.capcat.ai/<site-key>/siteverify",
data={"secret": CAPCAT_SECRET, "response": request.form["cap-token"]})从 Turnstile 迁移
前端
html
<!-- 之前 -->
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<div class="cf-turnstile" data-sitekey="<turnstile-site-key>"></div>
<!-- 之后 -->
<script src="https://capcat.ai/widget/cap.js"></script>
<cap-widget data-cap-api-endpoint="https://api.capcat.ai/<site-key>/"></cap-widget>服务端
Turnstile 的 siteverify 支持 JSON 与表单编码,Capcat 同样两者都支持——只改 URL、secret 与字段名(cf-turnstile-response → cap-token):
js
// 之前
const r = await fetch("https://challenges.cloudflare.com/turnstile/v0/siteverify", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ secret: TURNSTILE_SECRET, response: token }),
});
// 之后
const r = await fetch("https://api.capcat.ai/<site-key>/siteverify", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ secret: CAPCAT_SECRET, response: token }),
});迁移注意事项
- token 一次性有效:siteverify 校验成功一次后立即失效,重放返回
success: false(与三家行为一致)。默认有效期 20 分钟。 - 没有评分与动作:响应里没有
score/action/hostname字段,通过判定只看success。 - 域名绑定:对应 reCAPTCHA / hCaptcha 的域名白名单,在控制台站点设置里配置「允许的域名」;绑定后其他来源的验证请求会被直接拒绝。
- 内容安全策略(CSP):若站点启用了严格 CSP,需放行
capcat.ai(脚本与 wasm)和api.capcat.ai(验证请求)。 - SPA / 自定义流程:不用表单提交时,监听组件的
solve事件拿 token,详见前端组件。
迁移过程中新旧验证可以并行:前端逐页替换,服务端按 token 字段名区分走哪家校验,全部切完后再移除旧依赖。