Cloudflare Turnstile
Cloudflare Turnstile 是 Cloudflare 的无感 / 勾选框(三种模式,由站点在后台选)。多数情况下是一个窄条组件,转一会儿就自动通过,不需要做任何事。少数配置下会出现一个要勾的方框——但**永远不会有图片题或要辨认的文字**(Cloudflare 官方原话:「There will be no images or text to decipher.」)。也有站点配成完全不显示。
接口规格
| 项目 | 值 |
|---|---|
| type | turnstile |
| 必填参数 | website_urlwebsite_key |
| 可选参数 | actioncdatapage_data |
| 返回 | 一个 token 字符串(solution.token) |
| 怎么用这个解 | 填回表单的 `cf-turnstile-response` |
| 价格 | $1.53 / 1K 次 —— 按成功计费,没解出来退款 |
| 厂商文档 | Cloudflare 官方文档 |
参数去页面哪里取
下面全部是可以直接照做的定位方法 —— DOM 属性名、JS 全局变量名、script 上的 query 参数。
必填 website_url + website_key,可选 action / cdata / page_data。
website_key(sitekey)——两个位置
1. 隐式渲染:容器 div 上带类名和属性
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-theme="light"
data-size="normal" data-callback="onSuccess"></div>一行取:document.querySelector('.cf-turnstile').dataset.sitekey
2. 显式渲染:sitekey 在 turnstile.render() 的第二个参数里
const widgetId = turnstile.render("#turnstile-container", {
sitekey: "<YOUR-SITE-KEY>", callback: function (token) { … },
});这时 DOM 上可能没有属性,去 DevTools 全局搜 turnstile.render。
判断是不是 Turnstile
看脚本域名 challenges.cloudflare.com(站点若开了 CSP 必须放行它,所以这个域一定出现)。控制台一句:typeof turnstile 返回 "object" 即是。
action / cdata
对应组件上的 data-action 与 data-cdata 属性(显式渲染时是 render 参数里的同名键)。站点没设就不用传 —— 它们是站点自己用来区分场景的标签,传错反而对不上。
回填
隐藏 input 的 name 是 `cf-turnstile-response`:
<input type="hidden" name="cf-turnstile-response" value="TOKEN_VALUE" />也可以用 turnstile.getResponse(widgetId) 现取。
三种模式怎么从页面看出来
(Cloudflare 官方 widget types)
· 完全看不到组件、也没有加载指示 → invisible
· 看得到组件、有转圈、但从不要求点击 → non-interactive
· 看得到组件、可能升级成要勾的方框 → managed(默认推荐档)
⚠ managed 与 non-interactive 在低风险访客身上外观可能一样(都是转一下就过),
真正的区别是「会不会升级成复选框」—— 官方流程图里 Interaction 状态标着 "Managed mode only"。
调用示例
一个端点解全部验证码类型 —— 换一种验证码只改 type 这一个字段。
curl -X POST https://api.everyinfra.com/api/v1/captcha \ -H "Authorization: Bearer omg_你的KEY" \ -H "Content-Type: application/json" \ -d '{"type":"turnstile","website_url":"<website_url>","website_key":"<website_key>"}'
{ "solution": { "token": "…" }, "billing": { "charged": true, "credits": 110 }}
怎么确认目标站用的就是它
组件向 challenges.cloudflare.com 取一段挑战,在浏览器里跑一组无感检测(浏览器行为与环境信号),通过后往表单里插一个隐藏 input,服务端再拿它去 siteverify 校验。**token 300 秒过期且一次性**。
容易搞混的
⚠⚠ 最重要的一条:Turnstile 与 Cloudflare 挑战页(俗称「5 秒盾」)不是一回事,我们也是两条不同的能力。 Turnstile 是站点主动放在表单里的小组件,交付一个 token 填回表单,type 传 turnstile;5 秒盾是 Cloudflare 在整页前面拦你、显示「正在检查您的浏览器」,交付的是一串 Cookie,type 传 cloudflare_challenge。判据:页面是整页被挡还是表单里多了个组件。另外与 CaptchaFox 也容易混——它的回填字段 cf-captcha-response 同样是 cf- 开头,但那是另一家(Scoria Labs),域名是 cdn.captchafox.com。
常见部署场景
- 已经用 Cloudflare 的站点做表单防护——登录、注册、找回密码、联系表单
- 从 reCAPTCHA 迁走的站点(Turnstile 免费且不依赖 Google)
- Webflow、Ghost 等托管平台的内置选项
- API 与 Webhook 的前置人机校验
已知的坑
token 300 秒(5 分钟)过期,且一次性——官方明写。拿到就得马上用,不能囤。
`api.js` 必须从 Cloudflare 的原始 URL 加载,不能代理也不能缓存(官方要求)。站点若自己镜像了这个脚本,行为会不一致。
只在 http:// / https:// 下工作,file:// 打开的本地页面拿不到挑战。
还有一种超时叫 challenge timed out:验证已经过了、但用户长时间没点提交,结果失效要重来。所以别在拿到 token 后放太久。
data-cdata 在「客户端渲染」那页官方文档里没有列出,只在 widget configurations 那页——照一页文档抄参数表会漏。
交互式 / 非交互式 / 隐藏式会自动识别,不用指定
自定义 User-Agent 对本类型无效,传了会被忽略
常见问题
Cloudflare Turnstile 要传哪些参数?
必填 website_url、website_key;可选 action、cdata、page_data。请求里 type 传 turnstile。
解出来的东西怎么用?
返回一个 token 字符串,取 solution.token。填回表单的 cf-turnstile-response
challenges.cloudflare.com 要去页面的哪里找?
重点找 challenges.cloudflare.com、turnstile.render、data-cdata。本页「参数去页面哪里取」一节写了全部位置与取法,含可直接粘进控制台的一行命令。
怎么确认目标站用的就是 Cloudflare Turnstile?
⚠⚠ 最重要的一条:Turnstile 与 Cloudflare 挑战页(俗称「5 秒盾」)不是一回事,我们也是两条不同的能力。 Turnstile 是站点主动放在表单里的小组件,交付一个 token 填回表单,type 传 turnstile;5 秒盾是 Cloudflare 在整页前面拦你、显示「正在检查您的浏览器」,交付的是一串 Cookie,type 传 cloudflare_challenge。判据:页面是整页被挡还是表单里多了个组件。另外与 CaptchaFox 也容易混——它的回填字段 cf-captcha-response 同样是 cf- 开头,但那是另一家(Scoria Labs),域名是 cdn.captchafox.com。
有什么容易踩的坑?
token 300 秒(5 分钟)过期,且一次性——官方明写。拿到就得马上用,不能囤。
多少钱一次,失败扣不扣?
$1.53 / 1K 次。按成功计费 —— 没解出来一律退款,所以失败不花钱。账单按次记,标价按每千次是为了让量级读得出来。