Usar proxies en Deno y Bun: guía práctica para desarrolladores

Guía code-first para configurar proxies residenciales en Deno y Bun con fetch, rotación de IPs, sesiones sticky, SOCKS5, reintentos y mejores prácticas de producción.

Using Proxies in Deno and Bun: A Code-First Guide
En este artículo

Si has intentado usar proxies en Deno y Bun pasando una URL de proxy a fetch(), probablemente notaste que la petición salió con tu IP real. No es un bug: las implementaciones nativas de fetch en ambos runtimes ignoran los proxies por defecto porque la especificación Fetch de WHATWG no define un mecanismo estándar para proxies HTTP. Cada runtime resuelve esto a su manera, y en esta guía verás exactamente cómo configurarlos, rotarlos y llevarlos a producción con ProxyHat.

Por qué fetch ignora los proxies en Deno y Bun

La especificación Fetch define cómo un navegador o runtime debe realizar peticiones HTTP, pero delega la conexión de red subyacente al "fetch record" y al algoritmo de obtención de red, que no incluye parámetros de proxy. Esto significa que fetch('https://example.com', { proxy: '...' }) no es estándar y, en la mayoría de runtimes, se ignora silenciosamente o lanza un error.

Deno y Bun abordan esto de forma distinta:

  • Deno expone Deno.createHttpClient({ proxy: { url, basicAuth } }), que devuelve un cliente HTTP personalizado que puedes pasar a fetch() mediante la opción { client }.
  • Bun añade una extensión propia: fetch(url, { proxy: 'http://user:pass@host:port' }) funciona directamente en una sola línea.

Para scraping serio, price monitoring o SERP tracking, necesitas controlar el proxy por petición, rotar IPs y mantener sesiones sticky. Veamos cómo hacerlo en cada runtime.

Configurar un proxy Deno con Deno.createHttpClient

El enfoque de Deno es explícito y type-safe. Creas un cliente HTTP con la configuración del proxy y lo pasas a cada llamada de fetch:

// deno run --allow-net --allow-env proxy_deno.ts

const PROXY_URL = "http://user-country-US:pass@gate.proxyhat.com:8080";

// Crear un cliente HTTP con proxy
const client = Deno.createHttpClient({
  proxy: {
    url: PROXY_URL,
    // Si el proxy requiere autenticación básica, también puedes pasarla aquí:
    // basicAuth: { username: "user-country-US", password: "pass" }
  },
});

// Usar el cliente en fetch
const res = await fetch("https://httpbin.org/ip", { client });
const body = await res.json();
console.log(body);
// { origin: "198.8.x.x" }  <- IP del proxy, no la tuya

La opción client es específica de Deno y no forma parte de la spec de Fetch, pero es la forma oficial y soportada de enrutar tráfico a través de un proxy. Puedes reutilizar el mismo cliente para múltiples peticiones, lo que habilita connection pooling y reduce la latencia.

Autenticación básica separada

Si prefieres no incluir credenciales en la URL, puedes pasar basicAuth por separado:

const client = Deno.createHttpClient({
  proxy: {
    url: "http://gate.proxyhat.com:8080",
    basicAuth: {
      username: "user-country-DE-city-berlin",
      password: "tu_password",
    },
  },
});

const res = await fetch("https://httpbin.org/headers", { client });
console.log(await res.json());

Configurar un proxy en Bun con fetch

Bun toma un enfoque más directo: la opción proxy se acepta directamente en fetch, sin necesidad de crear un cliente intermedio:

// bun run proxy_bun.ts

const proxyUrl = "http://user-country-US:pass@gate.proxyhat.com:8080";

const res = await fetch("https://httpbin.org/ip", {
  proxy: proxyUrl,
});

const data = await res.json();
console.log(data);
// { origin: "198.8.x.x" }

Esto es más conciso, pero ten en cuenta que proxy es una extensión de Bun y no funcionará en Node.js ni en Deno. Si necesitas código portable entre runtimes, considera usar el SDK de ProxyHat (más abajo) o una capa de abstracción.

Geo-targeting y sesiones sticky en el username

ProxyHat codifica el geo-targeting y las sesiones sticky directamente en el nombre de usuario. Esto funciona igual en Deno y Bun:

ParámetroSintaxis en usernameEjemplo completo
Paísuser-country-UShttp://user-country-US:pass@gate.proxyhat.com:8080
País + ciudaduser-country-DE-city-berlinhttp://user-country-DE-city-berlin:pass@gate.proxyhat.com:8080
Sesión stickyuser-session-abc123http://user-session-abc123:pass@gate.proxyhat.com:8080
País + sesiónuser-country-US-session-abc123http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080
SOCKS5Puerto 1080socks5://user-country-US:pass@gate.proxyhat.com:1080

SOCKS5 en Deno

// Deno soporta SOCKS5 vía createHttpClient
const socksClient = Deno.createHttpClient({
  proxy: {
    url: "socks5://user-country-US-session-s1:pass@gate.proxyhat.com:1080",
  },
});

const res = await fetch("https://httpbin.org/ip", { client: socksClient });
console.log(await res.json());

SOCKS5 en Bun

const res = await fetch("https://httpbin.org/ip", {
  proxy: "socks5://user-country-US-session-s1:pass@gate.proxyhat.com:1080",
});
console.log(await res.json());

SOCKS5 es útil cuando necesitas túneles TCP completos o cuando el destino bloquea conexiones desde proxies HTTP conocidos. La latencia típicamente es 10-50ms mayor que con HTTP CONNECT, pero la compatibilidad con protocolos es más amplia.

Variables de entorno HTTP_PROXY y HTTPS_PROXY

Tanto Deno como Bun respetan las variables de entorno HTTP_PROXY y HTTPS_PROXY en algunos contextos, pero el comportamiento no es consistente. En Deno, Deno.createHttpClient puede leer automáticamente estas variables si no se especifica proxy:

// Configurar variables de entorno
// export HTTP_PROXY="http://user-country-US:pass@gate.proxyhat.com:8080"
// export HTTPS_PROXY="http://user-country-US:pass@gate.proxyhat.com:8080"

// Deno: el cliente puede usar las env vars automáticamente
const client = Deno.createHttpClient({});
// Si HTTP_PROXY está seteado, se usará automáticamente

const res = await fetch("https://httpbin.org/ip", { client });

Cuándo usar variables de entorno vs configuración por cliente:

  • Env vars: ideal para desarrollo local, debugging rápido o cuando toda la app usa un único proxy.
  • Configuración por cliente: necesario cuando rotas entre múltiples proxies, geo-targetings o sesiones en la misma aplicación.

Para scraping profesional, casi siempre necesitas configuración por cliente porque rotas IPs por petición. Las env vars son demasiado rígidas para ese caso.

Rotación de IPs residenciales con sesiones sticky concurrentes

Los proxies residenciales son necesarios cuando el sitio objetivo bloquea rangos de IPs de datacenters. Muchos sitios de e-commerce, redes sociales y motores de búsqueda detectan y bloquean IPs de datacenters con tasas de bloqueo que pueden superar el 80%. Los proxies residenciales usan IPs asignadas a hogares reales por ISPs legítimos, lo que reduce drásticamente las bloqueos.

Aquí tienes un ejemplo completo que rota un pool de sesiones sticky en peticiones concurrentes, con timeout vía AbortController:

// deno run --allow-net rotate_sessions.ts
// o: bun run rotate_sessions.ts (adaptando el cliente)

const PROXY_HOST = "gate.proxyhat.com";
const PROXY_PORT = 8080;
const PROXY_USER = "tu_usuario";
const PROXY_PASS = "tu_password";

// Generar IDs de sesión únicos
function makeSessionId(): string {
  return `sess-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
}

// Crear un cliente proxy con país y sesión sticky
function createProxyClient(country: string, sessionId: string) {
  const username = `${PROXY_USER}-country-${country}-session-${sessionId}`;
  const proxyUrl = `http://${username}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}`;

  // En Deno:
  return Deno.createHttpClient({ proxy: { url: proxyUrl } });
  // En Bun, devuelve { proxy: proxyUrl } y pásalo a fetch
}

// Fetch con timeout y reintentos
async function fetchWithRetry(
  url: string,
  client: Deno.HttpClient,
  maxRetries = 3,
  timeoutMs = 15000
): Promise<Response> {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const controller = new AbortController();
    const timeout = setTimeout(() => controller.abort(), timeoutMs);

    try {
      const res = await fetch(url, { client, signal: controller.signal });
      clearTimeout(timeout);

      if (res.status === 429 || res.status >= 500) {
        // Backoff exponencial: 1s, 2s, 4s
        const delay = Math.pow(2, attempt) * 1000;
        await new Promise((r) => setTimeout(r, delay));
        continue;
      }

      return res;
    } catch (err) {
      clearTimeout(timeout);
      if (attempt === maxRetries - 1) throw err;
      await new Promise((r) => setTimeout(r, Math.pow(2, attempt) * 1000));
    }
  }
  throw new Error("Max retries exceeded");
}

// Pool de países para rotación
const countries = ["US", "DE", "GB", "FR", "JP"];
const targetUrl = "https://httpbin.org/ip";

// Lanzar 10 peticiones concurrentes, cada una con su propia sesión sticky
const tasks = Array.from({ length: 10 }, (_, i) => {
  const country = countries[i % countries.length];
  const sessionId = makeSessionId();
  const client = createProxyClient(country, sessionId);

  return fetchWithRetry(targetUrl, client)
    .then((res) => res.json())
    .then((data) => ({ session: sessionId, country, ip: data.origin }))
    .catch((err) => ({ session: sessionId, error: err.message }));
});

const results = await Promise.all(tasks);
console.table(results);

Cada petición obtiene su propia sesión sticky, lo que significa que todas las peticiones dentro de una sesión saldrán con la misma IP residencial. Esto es crítico para sitios que requieren login o que detectan cambios de IP sospechosos dentro de una sesión.

Equivalente en Bun

// bun run rotate_sessions_bun.ts

const PROXY_HOST = "gate.proxyhat.com";
const PROXY_PORT = 8080;
const PROXY_USER = "tu_usuario";
const PROXY_PASS = "tu_password";

function makeSessionId(): string {
  return `sess-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
}

function makeProxyUrl(country: string, sessionId: string): string {
  const username = `${PROXY_USER}-country-${country}-session-${sessionId}`;
  return `http://${username}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}`;
}

async function fetchWithRetry(
  url: string,
  proxyUrl: string,
  maxRetries = 3,
  timeoutMs = 15000
): Promise<Response> {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const controller = new AbortController();
    const timeout = setTimeout(() => controller.abort(), timeoutMs);

    try {
      const res = await fetch(url, {
        proxy: proxyUrl,
        signal: controller.signal,
      });
      clearTimeout(timeout);

      if (res.status === 429 || res.status >= 500) {
        await new Promise((r) => setTimeout(r, Math.pow(2, attempt) * 1000));
        continue;
      }
      return res;
    } catch (err) {
      clearTimeout(timeout);
      if (attempt === maxRetries - 1) throw err;
      await new Promise((r) => setTimeout(r, Math.pow(2, attempt) * 1000));
    }
  }
  throw new Error("Max retries exceeded");
}

const countries = ["US", "DE", "GB", "FR", "JP"];
const targetUrl = "https://httpbin.org/ip";

const tasks = Array.from({ length: 10 }, (_, i) => {
  const country = countries[i % countries.length];
  const sessionId = makeSessionId();
  const proxyUrl = makeProxyUrl(country, sessionId);

  return fetchWithRetry(targetUrl, proxyUrl)
    .then((res) => res.json())
    .then((data) => ({ session: sessionId, country, ip: data.origin }))
    .catch((err) => ({ session: sessionId, error: err.message }));
});

const results = await Promise.all(tasks);
console.table(results);

Consejos de producción

Reintentos con backoff exponencial

Los proxies residenciales pueden fallar ocasionalmente porque dependen de IPs reales que pueden desconectarse. Implementa siempre backoff exponencial con jitter:

function backoffWithJitter(attempt: number, baseMs = 1000): number {
  const exponential = Math.pow(2, attempt) * baseMs;
  const jitter = Math.random() * 500;
  return exponential + jitter;
}

// Usar en el catch: await new Promise(r => setTimeout(r, backoffWithJitter(attempt)));

Certificados CA personalizados en Deno

Si haces scraping de sitios con certificados autofirmados o necesitas inyectar un CA corporativo, Deno lo soporta vía caCerts:

const caCert = await Deno.readTextFile("./custom-ca.pem");

const client = Deno.createHttpClient({
  proxy: {
    url: "http://user-country-US:pass@gate.proxyhat.com:8080",
  },
  caCerts: [caCert],
});

const res = await fetch("https://internal-site.local/api", { client });

Reutilización de conexiones

Crear un Deno.createHttpClient por petición tiene overhead. Para alta concurrencia, reutiliza clientes cuando sea posible. Si rotas entre N sesiones, crea un pool de N clientes y reutilízalos:

class ProxyPool {
  private clients: Map<string, Deno.HttpClient> = new Map();

  getClient(country: string, sessionId: string): Deno.HttpClient {
    const key = `${country}-${sessionId}`;
    if (!this.clients.has(key)) {
      const username = `${PROXY_USER}-country-${country}-session-${sessionId}`;
      const proxyUrl = `http://${username}:${PROXY_PASS}@gate.proxyhat.com:8080`;
      this.clients.set(key, Deno.createHttpClient({ proxy: { url: proxyUrl } }));
    }
    return this.clients.get(key)!;
  }

  // Limpieza periódica para evitar fugas de memoria
  cleanup(maxAgeMs = 300000) {
    // Implementar lógica de expiración según tu caso
  }
}

Logging estructurado

function logRequest(sessionId: string, url: string, status: number, ms: number) {
  console.log(JSON.stringify({
    timestamp: new Date().toISOString(),
    session: sessionId,
    url,
    status,
    latency_ms: ms,
  }));
}

const start = performance.now();
const res = await fetchWithRetry(url, client);
logRequest(sessionId, url, res.status, Math.round(performance.now() - start));

SDK de ProxyHat para Node (compatible con Deno y Bun)

Si necesitas abstraer la configuración del proxy o mantener compatibilidad entre runtimes, puedes usar el enfoque basado en env vars o construir un helper. Aquí tienes un ejemplo de un wrapper que funciona en ambos runtimes:

// proxyhat.ts — compatible con Deno y Bun

export interface ProxyConfig {
  username: string;
  password: string;
  country?: string;
  city?: string;
  session?: string;
  socks?: boolean;
}

export function buildProxyUrl(config: ProxyConfig): string {
  const scheme = config.socks ? "socks5" : "http";
  const port = config.socks ? 1080 : 8080;

  let username = config.username;
  if (config.country) username += `-country-${config.country}`;
  if (config.city) username += `-city-${config.city}`;
  if (config.session) username += `-session-${config.session}`;

  return `${scheme}://${username}:${config.password}@gate.proxyhat.com:${port}`;
}

// Helper para Deno
export function denoClient(config: ProxyConfig) {
  return Deno.createHttpClient({ proxy: { url: buildProxyUrl(config) } });
}

// Helper para Bun (devuelve opciones de fetch)
export function bunProxyOptions(config: ProxyConfig) {
  return { proxy: buildProxyUrl(config) };
}

Uso:

// Deno
import { denoClient } from "./proxyhat.ts";
const client = denoClient({
  username: "mi_user",
  password: "mi_pass",
  country: "US",
  session: "order-123",
});
const res = await fetch("https://api.example.com/data", { client });

// Bun
import { bunProxyOptions } from "./proxyhat.ts";
const opts = bunProxyOptions({
  username: "mi_user",
  password: "mi_pass",
  country: "US",
  session: "order-123",
});
const res = await fetch("https://api.example.com/data", opts);

Consulta la documentación oficial de ProxyHat para más detalles sobre parámetros avanzados.

Comparación: Deno vs Bun para proxies

CaracterísticaDenoBun
Configuración de proxyDeno.createHttpClient({ proxy }) + { client }fetch(url, { proxy }) directo
SOCKS5Sí, vía createHttpClientSí, vía { proxy }
CA personalizadoSí, caCertsLimitado
Connection poolingReutilizar HttpClientAutomático
Env vars HTTP_PROXYParcialParcial
Stdlib compatiblePropia stdlibNode-compatible

Consideraciones éticas y legales

El scraping web opera en un terreno legal complejo. En Estados Unidos, la Computer Fraud and Abuse Act (CFAA) prohíbe el acceso no autorizado a sistemas protegidos, aunque la jurisprudencia reciente (caso Van Buren v. United States, 2021) ha limitado su alcance. En la Unión Europea, el GDPR regula el procesamiento de datos personales, y la Directiva de Bases de Datos protege colecciones de datos sustanciales.

Mejores prácticas:

  • Usa APIs oficiales primero: si el sitio ofrece una API pública o pagada, úsala antes de scrapear.
  • Respeta robots.txt: revisa /robots.txt antes de scrapear cualquier sitio.
  • Solo datos públicos: no accedas a áreas que requieren login sin autorización explícita.
  • Rate limiting razonable: mantén una tasa de peticiones que no degrade el servicio objetivo (1-2 req/seg es un buen punto de partida).
  • GDPR: si recolectas datos personales de usuarios europeos, necesitas base legal (consentimiento, interés legítimo, etc.).
  • CCPA: en California, los consumidores tienen derecho a saber qué datos recolectas y a solicitar su eliminación.

Los proxies no te eximen de cumplir la ley. Usan IPs residenciales para evitar bloqueos técnicos, pero no convierten el scraping no autorizado en legal.

Casos de uso reales

  • SERP tracking: monitorizar posiciones en Google/Bing para SEO. Requiere rotación de IPs porque Google bloquea peticiones automatizadas tras ~100 requests desde la misma IP. Consulta nuestro caso de uso de SERP tracking.
  • Price monitoring: comparar precios en e-commerce. Los sitios como Amazon implementan anti-bot agresivo. Ver web scraping.
  • QA distribuido: verificar que tu sitio se renderiza correctamente desde distintos países.
  • Ad verification: confirmar que tus anuncios se muestran correctamente en geografías específicas.

Para ver la cobertura geográfica disponible, visita nuestras ubicaciones y los planes de pricing.

Errores comunes y edge cases

1. Olvidar el flag --allow-net en Deno

Deno requiere permisos explícitos. Sin --allow-net, las peticiones fallarán silenciosamente:

// Incorrecto: deno run script.ts
// Correcto: deno run --allow-net --allow-env script.ts

2. No manejar timeouts

Los proxies residenciales pueden ser lentos (200-800ms vs 50-100ms de datacenter). Sin timeout, una petición colgada puede bloquear tu pipeline entero:

// SIEMPRE usa AbortController
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 15000);
try {
  const res = await fetch(url, { client, signal: controller.signal });
} finally {
  clearTimeout(timeout);
}

3. Crear un cliente nuevo por petición sin cleanup

Deno.createHttpClient mantiene recursos abiertos. Si creas miles de clientes sin cerrarlos, puedes agotar file descriptors:

// Deno: cerrar cliente cuando ya no se necesita
client.close();

4. Mezclar HTTP y HTTPS incorrectamente

El proxy URL usa http:// (el protocolo del proxy), no https://, incluso si el destino es HTTPS. El proxy hace CONNECT tunneling:

// Correcto: proxy es http, destino es https
fetch("https://api.example.com", { proxy: "http://user:pass@gate.proxyhat.com:8080" })

// Incorrecto: no uses https para la URL del proxy
// fetch("https://api.example.com", { proxy: "https://user:pass@gate.proxyhat.com:8080" })

Key Takeaways

  • fetch() nativo no soporta proxies por defecto en ningún runtime; Deno usa Deno.createHttpClient y Bun usa { proxy } directo en fetch.
  • El geo-targeting y las sesiones sticky se codifican en el username: user-country-US-session-abc123.
  • SOCKS5 está disponible en el puerto 1080 para ambos runtimes.
  • Usa AbortController con timeout en cada petición proxy; los proxies residenciales pueden tardar 200-800ms.
  • Implementa backoff exponencial con jitter para reintentos; 3 intentos es un buen mínimo.
  • Reutiliza clientes HTTP en Deno para connection pooling; ciérralos con client.close().
  • Usa proxies residenciales para objetivos con bloqueo agresivo (e-commerce, SERPs, redes sociales).
  • Respeta robots.txt, usa APIs oficiales cuando existan, y cumple CFAA/GDPR/CCPA.

Preguntas frecuentes

¿Qué es usar proxies en Deno y Bun?

Es la configuración de proxies HTTP o SOCKS5 en los runtimes JavaScript modernos Deno y Bun. Deno requiere crear un cliente con Deno.createHttpClient({ proxy: { url } }) y pasarlo a fetch como { client }. Bun acepta la opción { proxy } directamente en fetch. Ambos enfoques permiten enrutar tráfico a través de gateways como gate.proxyhat.com:8080 para ocultar tu IP, rotar identidades y geo-targetar peticiones.

¿Por qué importan los proxies en Deno y Bun para usuarios de proxies?

Porque Deno y Bun son cada vez más populares para scraping y automatización gracias a su startup rápido, soporte nativo de TypeScript y APIs modernas. Sin soporte de proxies, no pueden usarse para scraping serio, SERP tracking o price monitoring. Saber configurar proxies correctamente —con rotación, sesiones sticky y geo-targeting— es esencial para evitar bloqueos y mantener tasas de éxito altas (>95%).

¿Qué tipo de proxy funciona mejor con Deno y Bun?

Los proxies residenciales son los mejores para objetivos con anti-bot agresivo (e-commerce, SERPs, redes sociales) porque usan IPs de ISPs reales que son difíciles de detectar. Los proxies de datacenter son más rápidos (50-100ms vs 200-800ms) pero se bloquean con más facilidad. Los proxies móviles ofrecen la mayor confianza pero son los más caros. Para Deno y Bun, la elección depende del caso de uso: datacenter para velocidad, residencial para evasión de bloqueos.

¿Cómo evitar bloqueos al implementar proxies en Deno y Bun?

Usa rotación de IPs con sesiones sticky por petición, implementa delays aleatorios entre peticiones (1-3 segundos), rota user-agents, usa headers realistas, limita la concurrencia a 5-10 peticiones simultáneas por dominio, implementa reintentos con backoff exponencial, y usa proxies residenciales en lugar de datacenter para sitios con WAF. Siempre configura AbortController con timeout de 10-15 segundos para evitar peticiones colgadas.

¿Puedo usar el mismo código de proxy en Deno y Bun?

No directamente, porque las APIs difieren: Deno usa Deno.createHttpClient y Bun usa { proxy } en fetch. Sin embargo, puedes crear un wrapper que detecte el runtime y use la API correspondiente, o usar variables de entorno HTTP_PROXY/HTTPS_PROXY como capa común. Otra opción es usar un helper que genere la URL del proxy (como el ejemplo proxyhat.ts de esta guía) y delegue al runtime correcto.

Preguntas frecuentes

¿Qué es usar proxies en Deno y Bun?

Es la configuración de proxies HTTP o SOCKS5 en los runtimes JavaScript modernos Deno y Bun. Deno requiere crear un cliente con Deno.createHttpClient({ proxy: { url } }) y pasarlo a fetch como { client }. Bun acepta la opción { proxy } directamente en fetch. Ambos enfoques permiten enrutar tráfico a través de gateways como gate.proxyhat.com:8080 para ocultar tu IP, rotar identidades y geo-targetar peticiones.

¿Por qué importan los proxies en Deno y Bun para usuarios de proxies?

Porque Deno y Bun son cada vez más populares para scraping y automatización gracias a su startup rápido, soporte nativo de TypeScript y APIs modernas. Sin soporte de proxies, no pueden usarse para scraping serio, SERP tracking o price monitoring. Saber configurar proxies correctamente con rotación, sesiones sticky y geo-targeting es esencial para evitar bloqueos y mantener tasas de éxito altas.

¿Qué tipo de proxy funciona mejor con Deno y Bun?

Los proxies residenciales son los mejores para objetivos con anti-bot agresivo porque usan IPs de ISPs reales que son difíciles de detectar. Los proxies de datacenter son más rápidos (50-100ms vs 200-800ms) pero se bloquean con más facilidad. Los proxies móviles ofrecen la mayor confianza pero son los más caros. La elección depende del caso de uso: datacenter para velocidad, residencial para evasión de bloqueos.

¿Cómo evitar bloqueos al implementar proxies en Deno y Bun?

Usa rotación de IPs con sesiones sticky por petición, implementa delays aleatorios entre peticiones (1-3 segundos), rota user-agents, usa headers realistas, limita la concurrencia a 5-10 peticiones simultáneas por dominio, implementa reintentos con backoff exponencial, y usa proxies residenciales en lugar de datacenter para sitios con WAF. Siempre configura AbortController con timeout de 10-15 segundos.

¿Puedo usar el mismo código de proxy en Deno y Bun?

No directamente, porque las APIs difieren: Deno usa Deno.createHttpClient y Bun usa { proxy } en fetch. Sin embargo, puedes crear un wrapper que detecte el runtime y use la API correspondiente, o usar variables de entorno HTTP_PROXY/HTTPS_PROXY como capa común. Otra opción es usar un helper que genere la URL del proxy y delegue al runtime correcto.

¿Listo para empezar?

Proxies residenciales, ISP y móviles en más de 148 países. Crea una cuenta gratis.

Crear cuenta gratis
← Volver al Blog