在 TypeScript 中安全处理 CAPTCHA 任务结果

作者:solvethree阅读需 1 分钟

读取 result.solution 前,先根据 result.status 进行分支处理。只有 ready 包含可用的解决结果,即便如此,也必须检查所请求产品需要的字段:Kasada 返回请求头,而 reCAPTCHA 和 TMPT 返回用途不同的令牌。

本页内容

读取解决结果前先收窄状态

输入使用 SDK 导出的 TaskRequest,响应使用 TaskResult。通过状态收窄,TypeScript 无需借助 any,也无需使用仅仅让编译器信任你的类型断言,就能区分未完成、失败和就绪状态。

TypeScript · 使用解决结果前先收窄任务状态类型
import { Solvethree, type TaskRequest, type TaskResult } from '@solvethree/sdk';
const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY! });
const input: TaskRequest = { site: 'accounts.example.com', action: 'login', proxy: process.env.SOLVETHREE_PROXY! };
function inspect(result: TaskResult): void {
  switch (result.status) {
    case 'pending':
    case 'solving':
      console.log('Retrieve this task again:', result.id);
      return;
    case 'failed':
      console.error('Failed task:', result.id, result.errorCode);
      return;
    case 'ready':
      // Solution fields depend on the requested product; check optional fields.
      if (!result.solution.token || !result.solution.userAgent || !result.solution.secChUa) {
        throw new Error('Expected a complete reCAPTCHA solution');
      }
      console.log('Ready task:', result.id);
      // Submit token privately with its browser identity and original proxy.
      return;
  }
}
inspect(await client.createTask(input, { waitMs: 0 }));
// Save the returned ID and call getTask while pending/solving with a deadline.

此示例创建一个任务并检查即时响应。pending 和 solving 表示需要再次获取该任务;failed 表示停止处理;ready 表示进入解决方案检查。如果将 ready 分支提取为辅助函数,请使用导出的 ReadyTask 类型作为参数类型。这会收窄状态类型,但不会让所有产品专属的解决方案字段都变为必填。

由于此输入请求的是 reCAPTCHA,守卫会检查令牌和两个浏览器身份字段。它们不能证明目标网站会接受该令牌。此示例特意不打印令牌。

  • 使用 Node.js 22+,并按 API 文档中的说明安装官方 SDK tarball;不要假定 npm 注册表中已有发布版本。
  • 在服务器环境中设置 SOLVETHREE_API_KEY 和 SOLVETHREE_PROXY。! 断言不会在运行时校验环境变量是否缺失。
  • 将 accounts.example.com 和 login 替换为所需的主机名和操作。该站点必须已在工作区中拥有有效的配置文件;请参阅站点配置文件设置。

使用已保存的 ID 轮询,不要新建任务

此示例将轮询交由调用方处理。请将创建操作放在循环之外:再次调用 createTask 并不是检查第一个任务是否完成的方法。

  1. 1.

    保存创建结果中的 ID

    在使用返回的 ID 获取任务之前,请检查它是否为非空字符串。将其与原始请求关联保存,选择成功的代理时也需要该请求。

  2. 2.

    获取同一个任务

    当状态为 pending 或 solving 时,使用已保存的 ID 调用 getTask,并设置本地截止时间。处理每个响应前,请检查其中的 ID 是否与已保存的 ID 一致。ID 一致只能确定你正在处理哪个任务,不能确定任务是否成功。

  3. 3.

    任务进入终态时停止

    状态为 ready 时,校验所请求产品必需的字段。状态为 failed 时,检查 errorCode 和 error,然后停止轮询该任务。请单独处理请求错误:获取请求失败本身并不意味着任务已进入失败终态。

如果创建操作在收到 ID 之前超时,不要假定任务未创建。如果提供了 requestId,使用相同值重新提交完全相同的请求即可找回现有任务。更改输入后复用该值会产生冲突;生成新值则无法找回原始任务。

就绪结果仍需使用正确的产品处理器

根据原始请求选择处理器,然后检查预期的解决方案字段。仅凭令牌是否存在,无法区分 reCAPTCHA 响应和 TMPT Cookie 值。

收窄为就绪状态后应使用的内容
收窄为就绪状态后应使用的内容
请求的产品解决方案值使用方式
reCAPTCHA Enterprisesolution.token作为指定主机名和操作的 reCAPTCHA 令牌提交。
KasadaTasksolution.headers将返回的标头一起应用。不要将此结果当作令牌。
TicketmasterTmptTasksolution.token用作原始 tmpt Cookie 值,而不是 reCAPTCHA 令牌。

独立 Kasada 目前支持 www.ticketmaster.com 上的 HTTPS 目标,不支持任意站点。其标头处理器并不是通用的 Kasada 集成方案。

对于每种产品,都应使用返回的 userAgent 和 secChUa 以及成功的代理进行提交。使用代理候选项时,请调用 successfulProxy(originalTask, readyResult),不要假定第一个候选项成功。SDK 不会替你将解决方案应用到目标网站,ready 也不保证后续请求会被接受。

运行您的第一个任务。

使用 $5 工作区额度开始体验。

创建工作区
在 TypeScript 中安全处理 CAPTCHA 任务结果 · solvethree