Вызов CAPTCHA API из Cloudflare Workers
Вызывайте API задач solvethree из Worker с помощью серверного fetch. Храните API-ключ рабочего пространства в привязке секрета, задавайте фиксированные входные данные целевого сайта в Worker и возвращайте ответы задач только авторизованному клиенту вашего приложения.
На этой странице
Настройте целевой сайт и секреты
Сначала активируйте профиль целевого сайта для своего рабочего пространства в консоли. Отправка имени хоста и действия не создаёт профиль. Если это обязательное условие ещё не выполнено, см. настройку профиля сайта.
SOLVETHREE_API_KEY: API-ключ вашего рабочего пространства, сохранённый как секрет Worker.INTEGRATION_KEY: отдельный секрет, который клиент вашего приложения должен передавать вx-integration-key.SOLVETHREE_PROXY: URL прокси, используемого для решения. Храните его как секрет, если он содержит учётные данные.CAPTCHA_SITE: имя целевого хоста, а не полный URL.
В примере действие зафиксировано как login и указан один прокси. Измените эти параметры развёрнутого Worker под свою интеграцию; не принимайте произвольные параметры целевого сайта от клиентов. Если recaptchaType не указан, API по умолчанию использует reCAPTCHA Enterprise v3.
Используйте ключ интеграции для обмена между доверенным клиентом приложения и Worker, а не в общедоступном браузерном коде. Это общие учётные данные, а не авторизация доступа к задачам для отдельных пользователей.
Создание и получение задач
export default {
async fetch(request, env) {
if (!env.INTEGRATION_KEY || request.headers.get('x-integration-key') !== env.INTEGRATION_KEY) {
return new Response('Unauthorized', { status: 401 });
}
const url = new URL(request.url);
const headers = { Authorization: `Bearer ${env.SOLVETHREE_API_KEY}`, 'Content-Type': 'application/json' };
let response;
if (request.method === 'POST') {
const requestId = request.headers.get('x-request-id');
if (!requestId || !/^[A-Za-z0-9_-]{1,64}$/.test(requestId)) return new Response('Provide X-Request-ID', { status: 400 });
response = await fetch('https://api.solvethree.com/v1/tasks?waitMs=0', {
method: 'POST', headers, redirect: 'error', signal: AbortSignal.timeout(20000),
body: JSON.stringify({ site: env.CAPTCHA_SITE, action: 'login', proxy: env.SOLVETHREE_PROXY, requestId }),
});
} else if (request.method === 'GET') {
const id = url.searchParams.get('id');
if (!id || !/^[A-Za-z0-9_-]{1,128}$/.test(id)) return new Response('Provide a valid id', { status: 400 });
response = await fetch(`https://api.solvethree.com/v1/tasks/${encodeURIComponent(id)}?waitMs=15000`, {
headers, redirect: 'error', signal: AbortSignal.timeout(25000),
});
} else return new Response('Use POST or GET', { status: 405 });
if (!response.ok) return Response.json({ error: 'Solver API request failed', status: response.status }, { status: response.status });
return Response.json(await response.json(), { headers: { 'Cache-Control': 'no-store' } });
},
};
// Store keys in Worker secret bindings. The task proxy field does not add a
// generic HTTP proxy option to Workers fetch; another client must submit through it.- 1.
Создайте задачу
Отправьте POST-запрос в Worker с
x-integration-keyиx-request-id. Выберите идентификатор запроса из 1–64 букв ASCII, цифр, знаков подчёркивания или дефисов. Worker формирует тело задачи из настроенных параметров целевого сайта и прокси; тело, переданное клиентом, не используется. - 2.
Сохраните идентификатор задачи
Worker возвращает JSON-ответ сервиса решения. Сохраните возвращённый идентификатор задачи и идентификатор запроса, использованный для её создания.
- 3.
Получите результат
Отправьте GET-запрос в Worker с идентификатором задачи в параметре запроса
idи тем же заголовком ключа интеграции. Обработчик проверяет синтаксис идентификатора и получает эту задачу из solvethree.
Оба запроса к API используют ключ рабочего пространства для аутентификации. Обработчик передаёт неуспешные HTTP-коды состояния с обобщённым сообщением об ошибке в теле ответа и помечает успешные JSON-ответы заголовком Cache-Control: no-store. Кроме проверки общего ключа интеграции, он не проверяет принадлежность задачи; добавьте такую авторизацию, прежде чем предоставлять отдельным пользователям доступ к получению задач.
Обрабатывайте тайм-ауты без создания новой задачи
При создании используются waitMs=0 и тайм-аут fetch в 20 секунд. При получении используются waitMs=15000 и тайм-аут fetch в 25 секунд. Эти ограничения действуют на отдельные HTTP-вызовы, а не на всё время существования задачи.
Если при создании произошёл тайм-аут до получения идентификатора задачи, повторите тот же запрос с тем же идентификатором запроса. Это позволит восстановить существующую задачу, если она была создана. Не генерируйте новый идентификатор только из-за сбоя соединения: первый запрос уже мог дойти до solvethree. Повторное использование идентификатора с изменёнными входными данными вызывает конфликт.
Пример не перехватывает исключения fetch, включая тайм-ауты. Добавьте обработку исключений, если клиенту нужен структурированный ответ об ошибке, но сохраните идентификатор запроса для восстановления.
pendingилиsolving: повторно запросите ту же задачу, соблюдая общий предельный срок, заданный в клиенте.ready: решение доступно; прекратите опрос и передайте его клиенту, выполняющему отправку.failed: прекратите опрос и проверьтеerrorCodeиerror. Устраните указанную проблему, прежде чем создавать другую задачу.
Ошибка HTTP и задача со статусом failed — разные виды сбоев. Обработчик сначала проверяет HTTP-статус; клиент всё равно должен проверить статус задачи в успешном ответе. Для диагностики см. ошибки CAPTCHA API.
Отправляйте решение через клиент с поддержкой прокси
Worker в примере обращается только к solvethree. Поле задачи proxy указывает сервису решения, какой прокси использовать; оно не меняет сетевую маршрутизацию Worker. У Workers fetch нет универсального параметра для URL прокси.
Передайте готовое решение клиенту, который может отправить его на нужный целевой сайт через тот же прокси. Используйте возвращённые в решении userAgent и secChUa, а не посторонние заголовки браузера. Готовая задача означает, что solvethree сгенерировал решение; его принятие зависит от последующего запроса к целевому сайту.
Источники и справочник API
Запустите первую задачу.
Начните с $5 на балансе рабочего пространства.