Usare Proxy in Deno e Bun: Guida Pratica per Sviluppatori JavaScript

Scopri come configurare proxy residenziali in Deno e Bun con esempi di codice pronti all'uso: fetch con proxy, rotazione IP, sessioni sticky e consigli di produzione.

Using Proxies in Deno and Bun: A Code-First Guide
In questo articolo

Perché Usare Proxy in Deno e Bun: Il Problema del fetch Nativo

Se hai mai provato a usare il fetch() nativo in Deno o Bun passando un proxy, probabilmente hai scoperto che l'opzione viene semplicemente ignorata. Il motivo è che le specifiche Fetch di WHATWG non includono il concetto di proxy: il browser gestisce i proxy a livello di sistema, non nell'API JavaScript. Deno e Bun ereditano questo comportamento di base, ma ognuno lo risolve a modo suo.

Usare proxy in Deno e Bun è essenziale per scraping web, monitoraggio SERP, raccolta dati per AI e qualsiasi scenario in cui il target blocca IP datacenter. I proxy residenziali offrono indirizzi IP reali associati a ISP legittimi, con tassi di successo significativamente più alti rispetto ai proxy datacenter su siti protetti.

Contesto Tecnico: Come Deno e Bun Gestiscono i Proxy

Deno e Bun affrontano il problema del proxy in modi diversi. Deno espone Deno.createHttpClient(), che restituisce un client HTTP personalizzabile da passare a fetch() tramite l'opzione client. Bun invece ha integrato il supporto proxy direttamente in fetch() con un'opzione proxy a livello di singola richiesta.

Entrambi i runtime supportano anche le variabili d'ambiente HTTP_PROXY e HTTPS_PROXY, ma la configurazione per-client offre un controllo granulare superiore, soprattutto quando devi gestire più pool di proxy con geo-targeting diverso.

Configurazione Base in Deno con Deno.createHttpClient

Il punto di ingresso per i proxy in Deno è Deno.createHttpClient(). Si passa un oggetto con la proprietà proxy, che contiene url e credenziali. Il client risultante si passa a fetch() come opzione client.

// Deno: proxy HTTP con autenticazione basic
const proxyUrl = "http://user-country-US:pass@gate.proxyhat.com:8080";

const client = Deno.createHttpClient({
  proxy: {
    url: proxyUrl,
  },
});

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

Per il geo-targeting a livello di città, basta modificare il nome utente con la sintassi ProxyHat:

// Deno: geo-targeting città + sessione sticky
const proxyUrl = "http://user-country-DE-city-berlin-session-abc123:pass@gate.proxyhat.com:8080";

const client = Deno.createHttpClient({
  proxy: { url: proxyUrl },
});

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

SOCKS5 in Deno

Per usare SOCKS5 su Deno, cambia la porta a 1080 e il protocollo nell'URL:

// Deno: SOCKS5 su porta 1080
const proxyUrl = "socks5://user-country-IT:pass@gate.proxyhat.com:1080";

const client = Deno.createHttpClient({
  proxy: { url: proxyUrl },
});

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

Configurazione Base in Bun: fetch con Proxy

Bun rende tutto più diretto: l'opzione proxy è accettata direttamente da fetch(). Non serve creare un client separato.

// Bun: proxy HTTP in una riga
const res = await fetch("https://httpbin.org/ip", {
  proxy: "http://user-country-US:pass@gate.proxyhat.com:8080",
});

const data = await res.json();
console.log(data);

Per le sessioni sticky con geo-targeting, la stessa sintassi del username si applica:

// Bun: sessione sticky + geo-targeting + SOCKS5
const res = await fetch("https://httpbin.org/ip", {
  proxy: "socks5://user-country-FR-session-sess42:pass@gate.proxyhat.com:1080",
});

console.log(await res.json());

Variabili d'Ambiente HTTP_PROXY / HTTPS_PROXY

Entrambi i runtime rispettano HTTP_PROXY e HTTPS_PROXY. Questo è utile per script CLI rapidi o quando non vuoi modificare il codice:

# Imposta le variabili d'ambiente
export HTTP_PROXY="http://user-country-US:pass@gate.proxyhat.com:8080"
export HTTPS_PROXY="http://user-country-US:pass@gate.proxyhat.com:8080"

# Esegui lo script
deno run --allow-net scraper.ts
# oppure
bun run scraper.ts

La configurazione per-client è preferibile quando: (1) gestisci più pool con geo-targeting diversi nello stesso processo, (2) hai bisogno di retry con proxy diversi, (3) vuoi evitare che le variabili d'ambiente influenzino altre librerie. Le variabili d'ambiente sono ideali per script monofunzione o ambienti containerizzate.

Rotazione di Sessioni Sticky con Promise.all e AbortController

I proxy residenziali sono cruciali per target ad alto rischio di blocco (e-commerce, social media, SERP). La strategia ottimale combina sessioni sticky (per mantenere l'IP coerente durante una sessione di richieste) con rotazione tra sessioni diverse per distribuire il carico.

Ecco un esempio completo in Bun che ruota un pool di sessioni sticky su richieste concorrenti, con timeout tramite AbortController:

// Bun: rotazione di sessioni sticky con timeout
const SESSIONS = ["sess-01", "sess-02", "sess-03", "sess-04", "sess-05"];
const TARGETS = [
  "https://httpbin.org/ip",
  "https://httpbin.org/headers",
  "https://httpbin.org/user-agent",
  "https://httpbin.org/ip",
  "https://httpbin.org/headers",
];

async function fetchWithProxy(url: string, session: string, timeoutMs = 10000) {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), timeoutMs);

  const proxy = `http://user-country-US-session-${session}:pass@gate.proxyhat.com:8080`;

  try {
    const res = await fetch(url, { proxy, signal: controller.signal });
    const body = await res.text();
    return { session, status: res.status, body };
  } catch (err) {
    return { session, status: 0, body: err instanceof Error ? err.message : "error" };
  } finally {
    clearTimeout(timer);
  }
}

// Esegui tutte le richieste in parallelo
const results = await Promise.all(
  TARGETS.map((url, i) => fetchWithProxy(url, SESSIONS[i]))
);

for (const r of results) {
  console.log(`[${r.session}] status=${r.status} len=${r.body.length}`);
}

Con 5 sessioni concorrenti e un timeout di 10 secondi, questo pattern può processare circa 50 richieste al minuto su un singolo nodo, con un tasso di successo tipico del 95%+ su target pubblici con proxy residenziali.

Produzione: Retry con Backoff, CA Personalizzate e Riutilizzo Connessioni

Retry con Backoff Esponenziale in Deno

// Deno: retry con backoff e rotazione sessioni
const MAX_RETRIES = 3;
const SESSIONS = ["r-01", "r-02", "r-03"];

async function fetchWithRetry(url: string) {
  for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
    const session = SESSIONS[attempt % SESSIONS.length];
    const proxyUrl = `http://user-country-GB-session-${session}:pass@gate.proxyhat.com:8080`;

    const client = Deno.createHttpClient({
      proxy: { url: proxyUrl },
    });

    const controller = new AbortController();
    const timer = setTimeout(() => controller.abort(), 8000);

    try {
      const res = await fetch(url, { client, signal: controller.signal });
      if (res.ok) return await res.text();
      console.warn(`Tentativo ${attempt + 1}: HTTP ${res.status}`);
    } catch (err) {
      console.warn(`Tentativo ${attempt + 1}: ${err}`);
    } finally {
      clearTimeout(timer);
    }

    // Backoff esponenziale: 1s, 2s, 4s
    await new Promise((r) => setTimeout(r, 1000 * 2 ** attempt));
  }
  throw new Error(`Tutte le ${MAX_RETRIES} richieste fallite per ${url}`);
}

const html = await fetchWithRetry("https://example.com");
console.log(`Lunghezza risposta: ${html.length} byte`);

CA Personalizzata in Deno

Se il tuo ambiente richiede una CA personalizzata (es. MITM aziendale), Deno supporta caCerts nel client:

// Deno: CA personalizzata
const caCert = await Deno.readTextFile("./my-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.corp.example.com", { client });
console.log(await res.text());

Confronto: ProxyHat Node SDK vs Configurazione Manuale

Il ProxyHat SDK per Node.js funziona anche sotto Deno e Bun grazie alla compatibilità npm. Ecco un confronto pratico:

AspettoConfigurazione manualeProxyHat SDK
Setup inizialeCostruire URL proxy a manoimport { ProxyHat } e configurazione dichiarativa
Rotazione IPLogica custom per sessioniRotazione automatica integrata
Retry/backoffImplementare da zeroIntegrato con policy configurabili
Geo-targetingEncoding manuale nel usernameAPI country() e city()
Compatibilità runtimeDeno, Bun, NodeDeno, Bun, Node (via npm)
// ProxyHat SDK sotto Bun (compatibilità npm)
import { ProxyHat } from "proxyhat";

const ph = new ProxyHat({
  username: "user",
  password: "pass",
  gateway: "gate.proxyhat.com",
  port: 8080,
});

// Richiesta con geo-targeting e rotazione automatica
const res = await ph.fetch("https://httpbin.org/ip", {
  country: "US",
  session: "auto",
});

console.log(await res.text());

Considerazioni Etiche e Legali

Lo scraping web opera in un'area grigia legale. Negli Stati Uniti, il Computer Fraud and Abuse Act (CFAA) regola l'accesso non autorizzato ai sistemi informatici. Nell'UE, il GDPR disciplina il trattamento dei dati personali. Linee guida pratiche:

  • Usa API ufficiali prima: se il sito offre un'API pubblica o un feed RSS, usalo. È più affidabile e legalmente sicuro.
  • Rispetta robots.txt: il file robots.txt indica cosa i proprietari del sito permettono di raccogliere.
  • Solo dati pubblici: evita di raccogliere dati dietro login o paywall senza autorizzazione esplicita.
  • Rate limiting responsabile: mantieni una velocità che non sovraccarichi il server target. 1-2 richieste per secondo per dominio è una buona baseline.
  • Conformità ToS: leggi i Termini di Servizio del sito target. Alcuni vietano esplicitamente lo scraping automatizzato.

Per approfondire i casi d'uso legittimi, consulta la nostra pagina su web scraping e SERP tracking.

Best Practices di Produzione

  • Connection reuse: riutilizza lo stesso Deno.createHttpClient() per più richieste alla stessa destinazione quando usi sessioni sticky. Questo riduce il overhead di TLS handshake del 30-50%.
  • Circuit breaker: se un proxy fallisce più di N volte consecutive, escludilo temporaneamente dal pool per 60 secondi prima di riprovare.
  • Logging strutturato: registra session ID, paese, status code e latenza per ogni richiesta. Questo rende il debug molto più semplice.
  • Monitoraggio del tasso di successo: se il tasso di successo scende sotto il 90%, è probabile che il target abbia aumentato le difese o che le sessioni siano state invalidate.

Key Takeaways

  • Deno usa Deno.createHttpClient({ proxy: { url } }) passato come { client } a fetch(); Bun usa fetch(url, { proxy }) direttamente.
  • Il geo-targeting e le sessioni sticky si codificano nel username: user-country-US-session-abc123.
  • SOCKS5 è disponibile sulla porta 1080; HTTP sulla porta 8080.
  • Per produzione, combina Promise.all con AbortController, retry con backoff e rotazione di sessioni.
  • Il ProxyHat SDK offre rotazione automatica e API dichiarativa, eseguibile su entrambi i runtime.
  • Usa sempre API ufficiali quando disponibili e rispetta robots.txt, ToS e normative locali.

Pronto a iniziare? Esplora i piani ProxyHat e le locazioni disponibili per configurare il tuo primo pool di proxy residenziali in Deno o Bun.

Domande frequenti

Come si usa un proxy con fetch in Deno?

In Deno si crea un client HTTP personalizzato con Deno.createHttpClient({ proxy: { url: 'http://user:pass@gate.proxyhat.com:8080' } }) e lo si passa a fetch come opzione client: fetch(url, { client }). Il fetch nativo di Deno ignora i proxy se non si usa questo approccio, perché le specifiche WHATWG Fetch non includono il concetto di proxy.

Come si configura un proxy in Bun fetch?

Bun supporta i proxy direttamente in fetch con l'opzione proxy: fetch('https://esempio.com', { proxy: 'http://user:pass@gate.proxyhat.com:8080' }). Non serve creare un client separato come in Deno. Bun accetta anche URL SOCKS5 per il proxy, usando la porta 1080 di ProxyHat.

Quale tipo di proxy è meglio per Deno e Bun?

I proxy residenziali sono i migliori per target ad alto rischio di blocco come e-commerce, social media e SERP, perché usano IP reali di ISP legittimi con tassi di successo superiori al 95%. I proxy datacenter sono più economici e veloci, ma vengono bloccati più facilmente. La scelta dipende dal caso d'uso: datacenter per API pubbliche, residenziali per siti protetti.

Come evitare blocchi usando proxy in Deno e Bun?

Per evitare blocchi: usa sessioni sticky per mantenere coerenza IP, ruota tra più sessioni per distribuire il carico, implementa retry con backoff esponenziale, imposta timeout con AbortController, rispetta robots.txt, mantieni rate limiting responsabile (1-2 richieste/sec per dominio) e usa geo-targeting appropriato per il target.

Si possono usare variabili d'ambiente HTTP_PROXY in Deno e Bun?

Sì, sia Deno che Bun rispettano le variabili d'ambiente HTTP_PROXY e HTTPS_PROXY. Sono utili per script CLI rapidi o ambienti containerizzate. Tuttavia, la configurazione per-client (Deno.createHttpClient o l'opzione proxy di Bun) è preferibile quando si gestiscono più pool con geo-targeting diverso nello stesso processo.

Verifica la tua configurazione proxy in pochi secondi

Verificatore di proxy gratuito — conferma che i tuoi IP siano veloci, anonimi e non bloccati.

Controlla i proxy gratis
← Torna al Blog