EveryInfra

Cloudflare Turnstile

Cloudflare TurnstileCloudflare无感 / 勾选框(三种模式,由站点在后台选)多数情况下是一个窄条组件,转一会儿就自动通过,不需要做任何事。少数配置下会出现一个要勾的方框——但**永远不会有图片题或要辨认的文字**(Cloudflare 官方原话:「There will be no images or text to decipher.」)。也有站点配成完全不显示。

正在查询可用性…$1.53 / 1K 次按成功计费,失败退款

接口规格

项目
typeturnstile
必填参数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-actiondata-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 挑战页 那一条 →

常见部署场景

已知的坑

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 次。按成功计费 —— 没解出来一律退款,所以失败不花钱。账单按次记,标价按每千次是为了让量级读得出来。

开始接入

一个端点覆盖全部验证码类型,按成功计费,失败与空结果一律退款。