Envía un token resuelto en una solicitud JSON de Playwright

Por solvethree5 min de lectura

Intercepta la solicitud POST JSON conocida de la aplicación y sustituye su campo de CAPTCHA por solution.token. Rellenar un área de texto no servirá si la aplicación construye su solicitud a partir del estado de JavaScript.

El siguiente ejemplo se dirige a un endpoint de envío del mismo origen en una aplicación propia. Conserva los demás campos JSON y las cabeceras de la solicitud en lugar de reconstruirla.

En esta página

Adapta el ejemplo a tu aplicación

  1. 1.

    Prepara el servicio de resolución

    Usa Node.js 22+, Playwright y el SDK oficial de JavaScript. Sigue las instrucciones de instalación del SDK; utiliza la descarga del paquete documentada en lugar de dar por hecho que está disponible en el registro de npm. Mantén SOLVETHREE_API_KEY en el proceso de Node.js, no en el código del navegador.

  2. 2.

    Configura el sitio y el proxy

    Establece TARGET_URL en tu página de pruebas propia y SOLVETHREE_PROXY en la URL de su proxy HTTP o HTTPS. El ejemplo solicita la acción login para el nombre de host de la página. Ese nombre de host necesita un perfil activo en el espacio de trabajo; primero configura el perfil del sitio. Cambia la acción si tu aplicación utiliza otra.

  3. 3.

    Identifica el envío exacto

    Establece TARGET_SUBMIT_URL en el endpoint POST de JSON, incluida su ruta. Debe compartir el origen de la página. El ejemplo espera un objeto que contenga recaptchaToken y un botón cuyo nombre accesible sea exactamente Submit. Cambia estos detalles específicos de la aplicación de forma conjunta.

Como entorno de prueba, usa una página que envíe un objeto JSON a ese endpoint y devuelva una respuesta que puedas inspeccionar. Incluye otro campo y un campo CSRF para comprobar que ninguno cambia. Un entorno local que solo devuelva los datos recibidos puede demostrar la modificación del JSON, pero no verifica la aceptación del CAPTCHA. El ejemplo proporcionado sigue realizando una resolución real y necesita un sitio configurado al que se pueda acceder a través del proxy.

Resuelve, intercepta y envía

Playwright · sustituir un parámetro de token JSON conocido
import { chromium } from 'playwright';
import { Solvethree } from '@solvethree/sdk';
const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY });
const target = new URL(process.env.TARGET_URL);
const proxy = new URL(process.env.SOLVETHREE_PROXY);
const result = await client.solve({ site: target.hostname, action: 'login', proxy: process.env.SOLVETHREE_PROXY });
const proxyConfig = { server: `${proxy.protocol}//${proxy.host}`, username: decodeURIComponent(proxy.username), password: decodeURIComponent(proxy.password) };

const submit = new URL(process.env.TARGET_SUBMIT_URL);
if (submit.origin !== target.origin) throw new Error('Use this demo with a same-origin submission URL');
const browser = await chromium.launch();
try {
  const context = await browser.newContext({ proxy: proxyConfig, userAgent: result.solution.userAgent,
    extraHTTPHeaders: { 'sec-ch-ua': result.solution.secChUa } });
  const page = await context.newPage();
  await page.route(submit.href, async route => {
    if (route.request().method() !== 'POST') return route.continue();
    const body = route.request().postDataJSON();
    if (!body || typeof body !== 'object' || Array.isArray(body)) throw new Error('Expected the known JSON object');
    await route.continue({ postData: JSON.stringify({ ...body, recaptchaToken: result.solution.token }),
      headers: { ...route.request().headers(), 'content-type': 'application/json' } });
  });
  await page.goto(target.href);
  const outcome = page.waitForResponse(r => r.url() === submit.href && r.request().method() === 'POST');
  await page.getByRole('button', { name: 'Submit', exact: true }).click();
  console.log('Application HTTP status:', (await outcome).status());
  // recaptchaToken, the Submit button and this endpoint belong to this demo app.
  // Adapt them to the real application, retaining its session/CSRF data.
  await context.close();
} finally { await browser.close(); }

client.solve crea la tarea y consulta su estado hasta que está lista o lanza una excepción. A continuación, el ejemplo crea un contexto de navegador con solution.userAgent, solution.secChUa y el mismo proxy único proporcionado para la resolución. El SDK no aplica la solución al navegador; eso lo hace el controlador de la ruta.

El contexto del navegador es nuevo. Si el envío requiere autenticación u otra configuración de sesión, realízala en este contexto antes de enviar. El ejemplo no importa ninguna sesión de navegador existente.

Sustituye el token, no toda la solicitud

La ruta se registra antes de la navegación y se limita a la URL de envío configurada. Las solicitudes que no son POST continúan sin cambios. En el caso de un POST, el controlador lee el objeto JSON existente, copia sus campos y sustituye únicamente recaptchaToken.

Así se conservan los campos del cuerpo, como los valores del formulario y los datos CSRF. El controlador también copia las cabeceras de la solicitud y establece el tipo de contenido en JSON. Conserva el comportamiento de sesión y CSRF existente de la aplicación; un token resuelto no sustituye a ninguno de los dos.

No amplíes la ruta a todas las solicitudes ni sustituyas cualquier campo que parezca un token. Inspecciona la solicitud saliente de la aplicación que controlas y usa el nombre real del campo. Este ejemplo no detecta widgets, no invoca callbacks arbitrarios ni admite páginas de terceros arbitrarias. La documentación de red de Playwright explica el mecanismo de interceptación.

Comprueba la respuesta de la aplicación

La espera de la respuesta comienza antes del clic y busca una coincidencia con la URL de envío y el método POST. El estado registrado corresponde a la respuesta de la aplicación, no a la tarea de solvethree. Inspecciona el cuerpo de esa respuesta o el estado resultante de la aplicación según sus propios criterios de éxito. Ni una tarea lista ni un estado HTTP de éxito demuestran por sí solos que la aplicación haya aceptado el token.

La espera de la respuesta nunca termina.

Comprueba si el botón Submit exacto genera un POST a la URL configurada.

Prueba esto: Corrige el localizador del botón, el endpoint o el método para que coincidan con la aplicación. No amplíes la interceptación a tráfico no relacionado.

La ruta no puede leer un objeto JSON.

Inspecciona el cuerpo de la solicitud y el tipo de contenido.

Prueba esto: Usa este controlador solo para el endpoint conocido que recibe un objeto JSON. Los datos de formulario, los arrays y otros formatos de carga útil necesitan un tratamiento diferente.

La tarea está lista, pero la aplicación rechaza el envío.

Comprueba que el JSON saliente contiene solution.token y revisa los datos de sesión/CSRF, la acción, la identidad de navegador devuelta y el proxy.

Prueba esto: Corrige la solicitud que no coincide antes de pagar otra resolución. Mantén el navegador en el proxy de la resolución y usa la identidad devuelta.

La resolución falla antes de que se abra el navegador.

Distingue entre un error de solicitud HTTP y un fallo terminal de la tarea. Si una tarea ha fallado, inspecciona errorCode y error.

Prueba esto: Corrige el problema de datos de entrada, perfil o conectividad indicado en lugar de reintentar con los mismos datos. Consulta la gestión de errores de la API.

Ejecuta tu primera tarea.

Empieza con $5 de crédito en tu espacio de trabajo.

Crear un espacio de trabajo
Envía un token resuelto en una solicitud JSON de Playwright · solvethree