跳转到主要内容
获取令牌时遇到问题吗
联系支持

Cloudflare Challenge

更多相关内容,请访问我们的博客
更多相关内容,请访问我们的博客
重要提示:

CapMonster Cloud 可以返回解决方案结果为 tokencf_clearance cookie。在开始之前,请先了解这两种选项,并选择最适合您使用场景的方式。

请求参数


重要:某些参数的值是动态的——它们会在包含 Cloudflare Challenge 的页面每次渲染时发生变化。
请在创建任务之前立即提取这些参数,以避免在求解过程中出现错误。
有关自动提取参数的示例,请参阅如何获取创建任务所需的所有参数


选项 1. Challenge(token)

注意!
  • CapMonster Cloud 默认使用内置代理 —— 费用已包含在服务中。仅在网站不接受 token 或访问内置服务受限时,才需要指定自己的代理。

  • 如果您使用 IP 授权的代理,请确保将地址 65.21.190.34 列入白名单。

  • 完成验证后,您将收到一个 token 用于确认验证码已完成。

type<string>required

TurnstileTask


websiteURL<string>required

需要解验证码的页面 URL


websiteKey<string>required

Turnstile 网站 key (参见章节 如何获取创建任务所需的所有参数)


cloudflareTaskType<string>required

token


pageAction<string>required

在回调函数中找到的 action 字段。如果使用 cloudflareTaskTypeaction 通常是 “managed” 或 “non-interactive”。


userAgent<string>required

浏览器 User-Agent。
请仅传递来自 Windows 系统的有效 UA。目前值为: userAgentPlaceholder


data<string>required

data 字段的值,从 cData 获取


pageData<string>required

pageData 的值,从 chlPageData 获取


apiJsUrl<string>optional

包含验证码脚本 URL 的字符串


proxyType<string>optional

http - 标准 http/https 代理;
https - 如果 "http" 不工作可尝试此类型(某些自定义代理需要);
socks4 - socks4 代理;
socks5 - socks5 代理


proxyAddress<string>optional

代理的 IP 地址 (IPv4/IPv6)。禁止:

  • 使用透明代理(会暴露客户端 IP);
  • 使用本机代理。


proxyPort<integer>optional

代理端口


proxyLogin<string>optional

代理登录名


proxyPassword<string>optional

代理密码


这些参数在创建验证码时传给 window.turnstile.render(el, paramsObj) 的对象中。你可以通过在加载其他脚本之前执行 JavaScript 来获取它们,例如:

(function () {
const obj = {
render: function () {
const { action, cData, chlPageData } = arguments[1];
const params = [
["action", action],
["data", cData],
["pageData", chlPageData],
];
console.table(params)
}
};

Object.defineProperty(window, "turnstile", {
get: () => {
return obj;
},
});
})();

window.turnstile.render(el, paramsObj) 被调用时,验证码会加载到页面上,成功完成后,callback 函数会传递解决方案信息。

window.turnstile.render(el, paramsObj):

  • el:插入验证码的 DOM 元素
  • paramsObj:包含验证码信息和解决指令的对象,通常包括 sitekeyactioncDatachlPageDatacallback
  • callback:验证码成功解决后调用的函数

选项 2. Challenge(cookie)

注意!
  • 本任务必须使用 自有代理

  • 完成后,你将收到 特殊的 cookie,需添加到浏览器中。

type<string>required

TurnstileTask


websiteURL<string>required

验证码所在页面的 URL


websiteKey<string>required

Turnstile 网站 key(可使用任意字符串)


cloudflareTaskType<string>required

cf_clearance


htmlPageBase64<string>required

Base64 编码的 HTML 页面,显示 403 响应时的 “Just a moment” 页面。
获取 htmlPageBase64 示例:

var serializer = new XMLSerializer();
var fullHtml = serializer.serializeToString(document);

var htmlBase64 = btoa(unescape(encodeURIComponent(fullHtml)));
console.log(htmlBase64);

userAgent<string>required

浏览器 User-Agent。
仅提供当前 Windows UA: userAgentPlaceholder


proxyType<string>required

http - 常规 HTTP/HTTPS 代理;
https - 如果 http 不可用使用(某些自定义代理需要);
socks4 - SOCKS4 代理;
socks5 - SOCKS5 代理


proxyAddress<string>required

代理 IP 地址 (IPv4/IPv6)。禁止:

  • 透明代理
  • 本机代理


proxyPort<integer>required

代理端口


proxyLogin<string>required

代理登录名


proxyPassword<string>required

代理密码


创建任务方法

选项 1. Challenge(token)

POST
https://api.capmonster.cloud/createTask

请求

{
"clientKey": "API_KEY",
"task": {
"type": "TurnstileTask",
"websiteURL": "https://example.com",
"websiteKey": "YOUR_WEBSITE_KEY_HERE",
"cloudflareTaskType": "token",
"userAgent": "userAgentPlaceholder",
"pageAction": "managed",
"pageData": "HUHDWUHuhuwfiweh32..uh2uhuhyugYUG=",
"data": "874291f4retD1366"
}
}

响应

{
"errorId": 0,
"taskId": 407533072
}

选项 2. Challenge(cookie)

POST
https://api.capmonster.cloud/createTask

请求

{
"clientKey": "API_KEY",
"task": {
"type": "TurnstileTask",
"websiteURL": "https://example.com",
"websiteKey": "xxxxxxxxxx",
"cloudflareTaskType": "cf_clearance",
"htmlPageBase64": "PCFET0NUWVBFIGh0...vYm9keT48L2h0bWw+",
"userAgent": "userAgentPlaceholder",
"proxyType": "http",
"proxyAddress": "8.8.8.8",
"proxyPort": 8080,
"proxyLogin": "proxyLoginHere",
"proxyPassword": "proxyPasswordHere"
}
}

响应

{
"errorId":0,
"taskId":407533072
}

获取任务结果方法

选项 1. Challenge(token)

POST
https://api.capmonster.cloud/getTaskResult

请求

{
"clientKey": "API_KEY",
"taskId": 407533072
}

响应

{
"errorId": 0,
"status": "ready",
"solution": {
"userAgent": "userAgentPlaceholder",
"token": "0.iGX3xsyFCkbGePM3jP4P4khLo6TrLukt8ZzBvwuQOvbC...f61f3082"
}
}

使用 getTaskResult 方法来获取 Challenge 的解决方案。根据系统负载,响应时间可能在 5 到 20 秒之间。

属性类型说明
tokenString在调用回调函数时使用此 token

选项 2. Challenge(cookie)

POST
https://api.capmonster.cloud/getTaskResult

请求

{
"clientKey": "API_KEY",
"taskId": 407533072
}

响应

{
"errorId": 0,
"status": "ready",
"solution": {
"cf_clearance": "1tarGvbY2_ZhQdYxpSBloao.FoOn9VtcJtmb_IQ_hCE-1761217338-1.2.1.1-vyVPoLYIGX0VCJomVuLjF7n0kdM0PXaPjpDsRcohxGr7hb2CE7WfcHpmQZ70goqEjdWxPsDhSVaKNTz9opxWguiNdWEEq_.SceWXIqfP7tnEb69f3bP0mixNqcWy_5P_9INpoAEqr1k7aYU0r45PT4gPr5pwHxedVySyLRdoBXIJasdTE52YOQ3NPdGWTwQ_3h2n_wYqqIvf0kCSAvimRrmsgZxomlyejwqPI6ZHi.w"
}
}
属性类型说明
cf_clearanceString特殊的 Cloudflare cookie,可在浏览器中设置

如何区分 Challenge 与 Turnstile

Challenge 与 Turnstile 的区别

Cloudflare 的验证类型可能会以不同形式出现。

标准 Turnstile:

样式化变体:

验证无缝集成到网站中

看起来像普通 Turnstile 验证,但实际上是 Cloudflare Challenge

要确认是否为 Challenge,可以打开开发者工具,检查网络流量,并查看页面源码中的典型标志:

  • 第一次请求站点时返回 403 状态码:

  • id 为 challenge-form 的表单,其 action 属性(不要与 Turnstile 的 action 混淆)包含参数 __cf_chl_f_tk=

  • 页面包含两个类似的 <script> 标签,在 window 对象中创建新的值:


如何获取创建任务所需的所有参数

自动化获取

要自动提取参数,可以通过 浏览器(普通或无头,例如使用 Playwright)或直接从 HTTP 请求 获取。由于动态参数有效期较短,建议在获取后立即使用。

重要提示!

提供的代码片段仅作为学习如何提取所需参数的基础示例。具体实现将取决于你的验证码页面、页面结构以及使用的 HTML 元素和选择器。

选项 1:Challenge(token)– Node.js
import { chromium } from "playwright";

(async () => {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();

let params = null;

try {
while (!params) {
await page.goto("https://example.com");

await page.evaluate(() => {
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
if (prop === "render") {
return function (a, b) {
const p = {
websiteKey: b.sitekey,
websiteURL: window.location.href,
data: b.cData,
pagedata: b.chlPageData,
action: b.action,
userAgent: navigator.userAgent,
};
window.params = p;
return target.render.apply(this, arguments);
};
}
return target[prop];
},
});
});

params = await page.evaluate(() => {
return new Promise((resolve) => {
setTimeout(() => resolve(window.params || null), 5000);
});
});

if (!params) {
await page.waitForTimeout(3000);
}
}

console.log("Turnstile Params:", params);
} finally {
await browser.close();
}
})();
选项 2:Challenge(cookie cf_clearance)– Node.js
import { chromium } from "playwright";
import { Buffer } from "buffer";

(async () => {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();

let websiteKey = null;

while (!websiteKey) {
await page.goto("https://example.com");

await page.evaluate(() => {
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
if (prop === "render") {
return function (a, b) {
// 保存 sitekey 到全局变量
window.websiteKey = b.sitekey;
return target.render.apply(this, arguments);
};
}
return target[prop];
},
});
});

websiteKey = await page.evaluate(() => {
return new Promise((resolve) => {
setTimeout(() => resolve(window.websiteKey || null), 5000);
});
});

if (!websiteKey) {
await page.waitForTimeout(3000);
}
}

// 获取页面 HTML 并转换为 Base64
const html = await page.content();
const htmlPageBase64 = Buffer.from(html).toString("base64");

const result = {
websiteKey,
htmlPageBase64,
};

console.log(result);

await browser.close();
})();

当然,这里是将你的说明文本翻译成中文,但代码保持不变:


使用 SDK 库

选项 1. Challenge(令牌)
// https://github.com/ZennoLab/capmonstercloud-client-js

import {
CapMonsterCloudClientFactory,
ClientOptions,
TurnstileRequest
} from '@zennolab_com/capmonstercloud-client';

const API_KEY = "YOUR_API_KEY"; // 输入您的 CapMonster Cloud API 密钥

document.addEventListener("DOMContentLoaded", async () => {
const client = CapMonsterCloudClientFactory.Create(
new ClientOptions({ clientKey: API_KEY })
);

// 基本示例,无需代理
// CapMonster Cloud 会自动使用它们的代理
let turnstileRequest = new TurnstileRequest({
websiteURL: "https://example.com", // 验证码页面的 URL
websiteKey: "YOUR_WEBSITE_KEY_HERE", // 替换为正确的值
data: "YOUR_DATA_HERE",
pageAction: "managed",
cloudflareTaskType: "token",
pageData: "YOUR_PAGE_DATA_HERE",
userAgent: "userAgentPlaceholder"
});

// 使用您自己的代理的示例
// 如果想使用自己的代理,请取消注释以下代码块

/*
const proxy = {
proxyType: "http",
proxyAddress: "123.45.67.89",
proxyPort: 8080,
proxyLogin: "username",
proxyPassword: "password"
};

turnstileRequest = new TurnstileRequest({
websiteURL: "https://example.com",
websiteKey: "YOUR_WEBSITE_KEY_HERE",
proxy,
data: "YOUR_DATA_HERE",
pageAction: "managed",
cloudflareTaskType: "token",
pageData: "YOUR_PAGE_DATA_HERE",
userAgent: "userAgentPlaceholder"
});
*/

// 如有必要,可以检查余额
const balance = await client.getBalance();
console.log("Balance:", balance);

const result = await client.Solve(turnstileRequest);
console.log("Solution:", result);
});
选项 2. Challenge(Cookie cf_clearance
// https://github.com/ZennoLab/capmonstercloud-client-js

import {
CapMonsterCloudClientFactory,
ClientOptions,
TurnstileRequest
} from '@zennolab_com/capmonstercloud-client';

document.addEventListener("DOMContentLoaded", async () => {
const cmcClient = CapMonsterCloudClientFactory.Create(
new ClientOptions({ clientKey: 'YOUR_API_KEY' }) // 输入您的 CapMonster Cloud API 密钥
);

// 如有必要,可以检查余额
const balance = await cmcClient.getBalance();
console.log('Balance:', balance);

const proxy = {
proxyType: "http",
proxyAddress: '123.45.67.89',
proxyPort: 8080,
proxyLogin: 'username',
proxyPassword: 'password'
};

// Cloudflare cf_clearance 只能使用您的代理解决
const turnstileRequest = new TurnstileRequest({
websiteURL: 'https://example.com/',
websiteKey: 'xxxxx',
cloudflareTaskType: 'cf_clearance',
proxy,
htmlPageBase64: 'PGh0bW...h0bWw+',
userAgent: 'userAgentPlaceholder'
});

// 发送验证码解决任务
const result = await cmcClient.Solve(turnstileRequest);
console.log('Solution:', result.solution);
});

Cloudflare Challenge (cf_clearance) 自动解决示例

这些示例展示了处理 Cloudflare Challenge 的基本流程:获取所需参数、在 CapMonster Cloud 中创建任务,以及在后续请求中使用 cf_clearance Cookie。您可以使用官方 SDK 或直接调用 API,根据您的集成需求选择合适的方式。

显示代码
import { ProxyAgent, setGlobalDispatcher } from "undici";

// ================= 配置(或使用 .ENV) =================

const API_KEY = "YOUR_API_KEY"; // 替换为您的 CapMonster Cloud API 密钥

const URL = "https://www.example.com"; // 替换为目标 URL
const SITEKEY = "xxxxxx";

const UA =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36";

// ================= 代理(替换为您的代理信息) =================

const PROXY_HOST = "PROXY_HOST";
const PROXY_PORT = 1234;
const PROXY_USER = "PROXY_USER";
const PROXY_PASS = "PROXY_PASS";

const proxy = new ProxyAgent(
`http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}`,
);

setGlobalDispatcher(proxy);

// ================= 会话 =================

let cookieHeader = "";

const headers = {
"User-Agent": UA,
Accept:
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
Connection: "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"sec-ch-ua":
'"Chromium";v="149", "Google Chrome";v="149", "Not:A-Brand";v="99"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
};

// ================= 获取页面 =================

async function fetchPage(url) {
const response = await fetch(url, {
method: "GET",
headers: {
...headers,
...(cookieHeader && {
Cookie: cookieHeader,
}),
},
});

const buffer = Buffer.from(await response.arrayBuffer());

return {
status: response.status,
body: buffer,
};
}

// ================= 带 JSON 的 POST 请求 =================

async function postJson(url, data) {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});

return await response.json();
}

// ================= 解决 =================

async function solveTurnstile(htmlBase64) {
const create = await postJson("https://api.capmonster.cloud/createTask", {
clientKey: API_KEY,
task: {
type: "TurnstileTask",
websiteURL: URL,
websiteKey: SITEKEY,
cloudflareTaskType: "cf_clearance",
htmlPageBase64: htmlBase64,
userAgent: UA,

proxyType: "http",
proxyAddress: PROXY_HOST,
proxyPort: PROXY_PORT,
proxyLogin: PROXY_USER,
proxyPassword: PROXY_PASS,
},
});

if (create.errorId) {
throw new Error(JSON.stringify(create));
}

const taskId = create.taskId;

console.log("任务 ID:", taskId);

while (true) {
await new Promise((resolve) => setTimeout(resolve, 5000));

const result = await postJson(
"https://api.capmonster.cloud/getTaskResult",
{
clientKey: API_KEY,
taskId,
},
);

if (result.errorId) {
throw new Error(JSON.stringify(result));
}

if (result.status === "ready") {
return result.solution.cf_clearance;
}

console.log("等待中...");
}
}

// ================= 主函数 =================

async function main() {
// 第一次请求

const first = await fetchPage(URL);

console.log("初始状态:", first.status);

console.log(first.body.toString("utf8").substring(0, 800));

// 解决

const htmlBase64 = first.body.toString("base64");

const cfClearance = await solveTurnstile(htmlBase64);

console.log("cf_clearance:", cfClearance);

cookieHeader = `cf_clearance=${cfClearance}`;

// 第二次请求

const second = await fetchPage(URL);

console.log("最终状态:", second.status);

console.log(second.body.toString("utf8").substring(0, 800));
}

main().catch(console.error);
显示代码 (SDK)
import { ProxyAgent, setGlobalDispatcher } from "undici";
import {
CapMonsterCloudClientFactory,
ClientOptions,
TurnstileRequest,
} from "@zennolab_com/capmonstercloud-client";

// ================= 配置(或使用 .ENV) =================

const API_KEY = "YOUR_API_KEY"; // 替换为您的 CapMonster Cloud API 密钥

const URL = "https://www.example.com"; // 替换为您的 URL
const SITEKEY = "xxxxxx";

const UA =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36";

// ================= 代理(替换为您的代理数据) =================

const PROXY_HOST = "PROXY_HOST";
const PROXY_PORT = 1234;
const PROXY_USER = "PROXY_USER";
const PROXY_PASS = "PROXY_PASSWORD";

const proxy = new ProxyAgent(
`http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}`,
);

setGlobalDispatcher(proxy);

// ================= 初始化 CAPMONSTER CLOUD SDK =================

const cmcClient = CapMonsterCloudClientFactory.Create(
new ClientOptions({ clientKey: API_KEY }),
);

// ================= 会话 =================

let cookieHeader = "";

const headers = {
"User-Agent": UA,
Accept:
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
Connection: "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"sec-ch-ua":
'"Chromium";v="149", "Google Chrome";v="149", "Not:A-Brand";v="99"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
};

// ================= 获取页面 =================

async function fetchPage(url) {
const response = await fetch(url, {
method: "GET",
headers: {
...headers,
...(cookieHeader && {
Cookie: cookieHeader,
}),
},
});

const buffer = Buffer.from(await response.arrayBuffer());

return {
status: response.status,
body: buffer,
};
}

// ================= 通过 SDK 解决 =================

async function solveTurnstile(htmlBase64) {
try {
// 检查余额(可选)
const balance = await cmcClient.getBalance();
console.log("余额:", balance);

// 创建解决请求
const turnstileRequest = new TurnstileRequest({
websiteURL: URL,
websiteKey: SITEKEY,
cloudflareTaskType: "cf_clearance",
htmlPageBase64: htmlBase64,
userAgent: UA,
proxy: {
proxyType: "http",
proxyAddress: PROXY_HOST,
proxyPort: PROXY_PORT,
proxyLogin: PROXY_USER,
proxyPassword: PROXY_PASS,
},
});

console.log("正在发送解决任务...");
const result = await cmcClient.Solve(turnstileRequest);

console.log("任务已解决!");
return result.solution.cf_clearance;
} catch (error) {
throw new Error(`CapMonster Cloud SDK 错误: ${error.message}`);
}
}

// ================= 主函数 =================

async function main() {
// 第一次请求

const first = await fetchPage(URL);

console.log("初始状态:", first.status);

console.log(first.body.toString("utf8").substring(0, 800));

// 解决

const htmlBase64 = first.body.toString("base64");

const cfClearance = await solveTurnstile(htmlBase64);

console.log("cf_clearance:", cfClearance);

cookieHeader = `cf_clearance=${cfClearance}`;

// 第二次请求

const second = await fetchPage(URL);

console.log("最终状态:", second.status);

console.log(second.body.toString("utf8").substring(0, 800));
}

main().catch(console.error);