Proxys in Deno und Bun nutzen: Code-First-Guide für JavaScript-Entwickler

Residential Proxys in Deno und Bun integrieren: Deno.createHttpClient, Bun fetch proxy, Geo-Targeting, Sticky Sessions, Retries und ethisches Scraping – mit lauffähigen Codebeispielen.

Using Proxies in Deno and Bun: A Code-First Guide for Modern JavaScript

Wenn Sie Proxys in Deno und Bun nutzen möchten, stellen Sie schnell fest, dass die native fetch()-API in beiden Runtimes Proxy-Konfigurationen standardmäßig ignoriert. Weder Deno noch Bun leiten Anfragen automatisch über einen Proxy-Server, es sei denn, Sie konfigurieren dies explizit. Dieser Leitfaden zeigt, wie Sie Residential Proxys in beiden modernen JavaScript-Runtimes produktiv einsetzen – mit lauffähigen Codebeispielen, Geo-Targeting, Sticky Sessions und Produktionstipps.

Warum Proxys in Deno und Bun nutzen – und warum fetch() sie ignoriert

Die WHATWG-fetch()-Spezifikation, die sowohl Deno als auch Bun implementieren, definiert keinen Proxy-Parameter. Die Browser-Implementierung delegiert Proxy-Konfiguration an die Netzwerkschicht des Browsers. In Node.js wurde Proxy-Unterstützung traditionstech über http.Agent oder Libraries wie undici gelöst. Deno und Bun haben jeweils eigene, unterschiedliche Ansätze gewählt, um diese Lücke zu schließen.

Der technische Grund ist einfach: fetch() baut direkt eine TCP-Verbindung zum Zielhost auf. Ohne eine Zwischenschicht, die den Traffic an einen Proxy umleitet, gibt es keinen Mechanismus, um die Anfrage umzuleiten. Beide Runtimes bieten jedoch native Lösungen – sie unterscheiden sich erheblich in der API-Gestaltung.

Warum Residential Proxys statt Datacenter-Proxys? Hochblockierende Ziele wie Google SERPs, E-Commerce-Plattformen oder Social-Media-APIs erkennen Datacenter-IP-Ranges (AWS, GCP, Hetzner) und blockieren sie häufig mit 403- oder 429-Antworten. Residential Proxys verwenden IPs echter ISPs und erreichen typischerweise 90–95 % höhere Erfolgsraten bei solchen Zielen. Mehr dazu auf unserer Web-Scraping-Use-Case-Seite.

FeatureDenoBun
Proxy-KonfigurationDeno.createHttpClient({ proxy })fetch(url, { proxy })
Basic Authproxy.basicAuthIn der Proxy-URL
Custom CA-ZertifikatecaCerts-OptionNoch nicht nativ
SOCKS5-UnterstützungÜber socks5://-URLÜber socks5://-URL
Env-Vars (HTTP_PROXY)Ja, automatischJa, automatisch

Deno: Deno.createHttpClient mit Proxy-Konfiguration

Deno löst das Proxy-Problem über Deno.createHttpClient(). Sie erzeugen einen konfigurierbaren HTTP-Client und übergeben ihn als { client }-Option an fetch(). Diese API ist stabil seit Deno 1.28 und bietet feingranulare Kontrolle über TLS, Proxys und Timeouts.

// deno run --allow-net proxy_fetch.ts

const proxyUrl = "http://gate.proxyhat.com:8080";
const username = "user-country-US";
const password = "dein_passwort";

const client = Deno.createHttpClient({
  proxy: {
    url: proxyUrl,
    basicAuth: `${username}:${password}`,
  },
  // Custom CA-Zertifikate für Self-Signed-Proxys
  caCerts: [],
});

try {
  const response = await fetch("https://httpbin.org/ip", {
    client,
  });
  const data = await response.json();
  console.log("Proxy-IP:", data.origin);
} catch (err) {
  console.error("Request fehlgeschlagen:", err.message);
} finally {
  client.close();
}

Beachten Sie, dass Sie client.close() aufrufen sollten, wenn der Client nicht mehr benötigt wird. Deno empfiehlt dies explizit in der offiziellen Deno-API-Dokumentation, um Ressourcenlecks zu vermeiden.

Geo-Targeting und Sticky Sessions im Username

ProxyHat kodiert Geo-Targeting und Session-IDs direkt im Benutzernamen. Das bedeutet, Sie müssen keine separate API aufrufen – alles passiert über die Proxy-URL.

// Sticky Session mit US-Geo-Targeting
const session = `sess-${crypto.randomUUID().slice(0, 8)}`;
const username = `user-country-US-session-${session}`;
const password = "dein_passwort";

const client = Deno.createHttpClient({
  proxy: {
    url: "http://gate.proxyhat.com:8080",
    basicAuth: `${username}:${password}`,
  },
});

// Alle Requests über diesen Client nutzen dieselbe IP
const res = await fetch("https://httpbin.org/ip", { client });
console.log(await res.json());
client.close();

SOCKS5 auf Port 1080

Für Anwendungen, die SOCKS5 benötigen (z. B. für UDP oder wenn HTTP-Proxys blockiert werden), nutzt ProxyHat Port 1080:

// SOCKS5 mit Stadt-Targeting (Berlin)
const username = "user-country-DE-city-berlin";
const password = "dein_passwort";

const socksClient = Deno.createHttpClient({
  proxy: {
    url: `socks5://${username}:${password}@gate.proxyhat.com:1080`,
  },
});

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

Bun: fetch mit proxy-Option

Bun geht einen pragmatischeren Weg: Die proxy-Option wird direkt an fetch() übergeben. Laut der Bun-Fetch-Dokumentation akzeptiert diese Option eine vollständige Proxy-URL inklusive Authentifizierung.

// bun run proxy_fetch.ts

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

try {
  const response = await fetch("https://httpbin.org/ip", {
    proxy: proxyUrl,
  });
  const data = await response.json();
  console.log("Proxy-IP:", data.origin);
} catch (err) {
  console.error("Request fehlgeschlagen:", err.message);
}

Für Sticky Sessions mit Geo-Targeting in Bun:

const sessionId = crypto.randomUUID().slice(0, 8);
const proxyUrl = `http://user-country-US-session-${sessionId}:dein_passwort@gate.proxyhat.com:8080`;

// Mehrere Requests über dieselbe Session
const targets = [
  "https://httpbin.org/ip",
  "https://httpbin.org/headers",
  "https://httpbin.org/user-agent",
];

const results = await Promise.all(
  targets.map((url) => fetch(url, { proxy: proxyUrl }).then((r) => r.json()))
);
console.log(results);

HTTP_PROXY und HTTPS_PROXY Umgebungsvariablen

Beide Runtimes unterstützen die Umgebungsvariablen HTTP_PROXY und HTTPS_PROXY. Dies ist nützlich für CLI-Tools oder wenn Sie Proxy-Logik zentral konfigurieren möchten:

// Terminal
// export HTTP_PROXY=http://user-country-GB:dein_passwort@gate.proxyhat.com:8080
// export HTTPS_PROXY=http://user-country-GB:dein_passwort@gate.proxyhat.com:8080

// Deno und Bun nutzen diese automatisch
const res = await fetch("https://httpbin.org/ip");
console.log(await res.json());

Wann sollten Sie per-Client-Konfiguration gegenüber Umgebungsvariablen bevorzugen?

  • Verschiedene Proxy-Parameter pro Request – z. B. verschiedene Länder oder Sessions.
  • Mehrere Proxys parallel – Umgebungsvariablen gelten global, was bei parallelen Requests mit unterschiedlichen Geo-Targets problematisch ist.
  • Testbarkeit – Explizite Konfiguration ist leichter zu testen als implizite Umgebungsvariablen.
  • Gezielte Deaktivierung – Manche Requests sollen den Proxy umgehen (z. B. interne APIs).

Residential Proxys für hochblockierende Ziele: Promise.all mit AbortController

Bei Zielen wie Google SERPs oder Ticketing-Plattformen reicht ein einzelner Proxy nicht aus. Sie benötigen mehrere Sticky Sessions, die parallel Anfragen stellen. Hier ist ein produktionsreifes Beispiel mit Promise.all und AbortController-Timeout:

// Deno oder Bun – funktioniert in beiden Runtimes

const PROXY_GATE = "http://gate.proxyhat.com:8080";
const PASSWORD = "dein_passwort";
const POOL_SIZE = 10;
const TIMEOUT_MS = 15000;

interface ProxyResult {
  sessionId: string;
  status: number;
  body: unknown;
  latencyMs: number;
}

async function fetchWithProxy(
  url: string,
  country: string,
  sessionId: string,
  clientBuilder?: (opts: { url: string; basicAuth: string }) => unknown
): Promise<ProxyResult> {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);

  const username = `user-country-${country}-session-${sessionId}`;
  const start = performance.now();

  try {
    let response: Response;

    // Deno-Pfad
    if (typeof Deno !== "undefined" && clientBuilder) {
      const client = clientBuilder({
        url: PROXY_GATE,
        basicAuth: `${username}:${PASSWORD}`,
      }) as Deno.HttpClient;
      response = await fetch(url, { client, signal: controller.signal });
    } else {
      // Bun-Pfad
      const proxyUrl = `http://${username}:${PASSWORD}@gate.proxyhat.com:8080`;
      response = await fetch(url, {
        proxy: proxyUrl,
        signal: controller.signal,
      });
    }

    const body = await response.json();
    const latencyMs = Math.round(performance.now() - start);

    return { sessionId, status: response.status, body, latencyMs };
  } catch (err) {
    console.error(`Session ${sessionId} fehlgeschlagen:`, err.message);
    throw err;
  } finally {
    clearTimeout(timeout);
  }
}

// Pool aus 10 Sticky Sessions für US-Traffic
const sessions = Array.from({ length: POOL_SIZE }, () =>
  crypto.randomUUID().slice(0, 8)
);

const target = "https://httpbin.org/ip";

const results = await Promise.allSettled(
  sessions.map((sid) => fetchWithProxy(target, "US", sid))
);

const succeeded = results.filter((r) => r.status === "fulfilled");
console.log(`Erfolgreich: ${succeeded.length}/${POOL_SIZE}`);

Dieses Muster rotiert über einen Pool von Sticky Sessions. Jede Session behält ihre IP für die Dauer der Anfrage – ideal für Ziele, die Cookie- oder IP-Konsistenz erwarten. Die AbortController-Logik stellt sicher, dass hängende Verbindungen nach 15 Sekunden abgebrochen werden.

Produktionstipps: Retries, Backoff und Verbindungswiederverwendung

Exponentieller Backoff mit Jitter

async function fetchWithRetry(
  url: string,
  proxyConfig: { username: string; password: string },
  maxRetries = 3,
  baseDelayMs = 1000
): Promise<Response> {
  let lastError: Error | null = null;

  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(url, {
        proxy: `http://${proxyConfig.username}:${proxyConfig.password}@gate.proxyhat.com:8080`,
      });

      // Bei 429 oder 5xx retry
      if (response.status === 429 || response.status >= 500) {
        throw new Error(`HTTP ${response.status} – Retry empfohlen`);
      }

      return response;
    } catch (err) {
      lastError = err as Error;
      const jitter = Math.random() * 500;
      const delay = baseDelayMs * Math.pow(2, attempt) + jitter;
      console.log(`Retry ${attempt + 1}/${maxRetries} nach ${Math.round(delay)}ms`);
      await new Promise((resolve) => setTimeout(resolve, delay));
    }
  }

  throw lastError;
}

Verbindungswiederverwendung in Deno

In Deno sollten Sie Deno.createHttpClient nicht pro Request neu erzeugen, wenn Sie dieselbe Proxy-Session verwenden. Erzeugen Sie den Client einmal und verwenden Sie ihn für mehrere Requests:

// Client einmal erzeugen, mehrfach verwenden
const stickyClient = Deno.createHttpClient({
  proxy: {
    url: "http://gate.proxyhat.com:8080",
    basicAuth: "user-country-DE-session-abc123:dein_passwort",
  },
  poolMaxSize: 20, // Verbindungspool
});

// 50 Requests über denselben Client (gleiche IP)
const urls = Array.from({ length: 50 }, (_, i) =>
  `https://httpbin.org/anything?req=${i}`
);

for (const url of urls) {
  const res = await fetch(url, { client: stickyClient });
  // Verarbeitung...
}

stickyClient.close();

Custom CA-Zertifikate in Deno

Wenn Sie hinter einem Corporate-Proxy sitzen oder Self-Signed-Zertifikate verwenden müssen, nutzt Deno die caCerts-Option:

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

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

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

ProxyHat Node SDK: Side-by-Side mit nativen APIs

Das ProxyHat Node SDK läuft unter beiden Runtimes, da es reines JavaScript/TypeScript ohne native Abhängigkeiten verwendet. Dies ist nützlich, wenn Sie Code zwischen Node.js, Deno und Bun teilen möchten:

// npm install @proxyhat/node-sdk
// oder: deno add @proxyhat/node-sdk (über npm: specifier)

import { ProxyHat } from "@proxyhat/node-sdk";

const proxy = new ProxyHat({
  username: "user-country-US",
  password: "dein_passwort",
  // SOCKS5: protocol: "socks5", port: 1080
});

// SDK erzeugt automatisch die korrekte Proxy-URL
const proxyUrl = proxy.getProxyUrl();
console.log(proxyUrl);
// => http://user-country-US:dein_passwort@gate.proxyhat.com:8080

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

// In Deno:
const denoClient = Deno.createHttpClient({
  proxy: {
    url: "http://gate.proxyhat.com:8080",
    basicAuth: proxy.getBasicAuth(),
  },
});
const denoRes = await fetch("https://httpbin.org/ip", { client: denoClient });
denoClient.close();

Vollständige Details finden Sie in der ProxyHat-Dokumentation. Aktuelle Preise und Pläne finden Sie auf unserer Preisseite, verfügbare Standorte auf der Locations-Seite.

Ethisches Scraping: Öffentliche Daten, CFAA und GDPR

Proxys sind ein Werkzeug, kein Freifahrtschein. Beachten Sie folgende Grundsätze:

  • Öffentliche Daten zuerst: Prüfen Sie, ob der Zielanbieter eine offizielle API anbietet. Viele Plattformen haben API-Tiers, die ausreichend für legitimate Use Cases sind.
  • CFAA (USA): Der Computer Fraud and Abuse Act kann das Umgehen von Zugriffsbeschränkungen kriminalisieren. Der Fall hiQ Labs v. LinkedIn (2022) bestätigte, dass das Scrapen öffentlicher Daten nicht zwangsläufig gegen den CFAA verstößt, aber die Rechtslage bleibt komplex.
  • GDPR (EU): Wenn Sie personenbezogene Daten verarbeiten, gilt die DSGVO – unabhängig davon, woher die Daten stammen. Stellen Sie sicher, dass Sie eine Rechtsgrundlage haben.
  • robots.txt und ToS: Respektieren Sie robots.txt und die Nutzungsbedingungen der Zielwebsite. Auch wenn nicht rechtlich bindend, sind sie ein guter ethischer Kompass.
  • Rate Limits: Auch mit Proxys sollten Sie Rate Limits respektieren. Aggressives Scraping kann Zielserver belasten.

ProxyHat-Proxys sind für legitimate Use Cases wie SERP-Tracking, Preisüberwachung, Sicherheitsforschung und QA-Automatisierung gedacht. Mehr dazu auf unserer SERP-Tracking-Use-Case-Seite.

Key Takeaways

  • Deno: Nutzen Sie Deno.createHttpClient({ proxy: { url, basicAuth } }) und übergeben Sie es als { client } an fetch.
  • Bun: Nutzen Sie fetch(url, { proxy: 'http://user:pass@gate.proxyhat.com:8080' }) – eine Zeile reicht.
  • Geo-Targeting: Kodieren Sie Land, Stadt und Session im Username: user-country-US-session-abc123.
  • SOCKS5: Port 1080 für SOCKS5, Port 8080 für HTTP.
  • Produktion: Retries mit exponentiellem Backoff, AbortController-Timeouts und Verbindungswiederverwendung.
  • Ethik: Öffentliche Daten, offizielle APIs zuerst, CFAA/GDPR beachten.

FAQ

Was bedeutet „Proxys in Deno und Bun nutzen"?

Es beschreibt die Konfiguration von HTTP- oder SOCKS5-Proxys in den modernen JavaScript-Runtimes Deno und Bun. Da die native fetch()-API keine Proxy-Parameter definiert, nutzt Deno Deno.createHttpClient und Bun eine proxy-Option in fetch(), um Traffic über einen Proxy-Server wie gate.proxyhat.com:8080 zu leiten.

Warum ist das für Proxy-Nutzer relevant?

Ohne explizite Proxy-Konfiguration baut fetch() direkt eine TCP-Verbindung zum Ziel auf. Für Web-Scraping, SERP-Tracking oder Preisüberwachung benötigen Sie jedoch eine andere IP, um Blöcken zu vermeiden. Residential Proxys erreichen bei hochblockierenden Zielen typischerweise 90–95 % Erfolgsrate, verglichen mit 30–50 % bei Datacenter-IPs.

Welcher Proxy-Typ eignet sich am besten?

Für hochblockierende Ziele (Google, E-Commerce, Social Media) sind Residential Proxys die beste Wahl, da sie IPs echter ISPs verwenden. Datacenter-Proxys sind schneller und günstiger, eignen sich aber eher für API-Anfragen ohne IP-basierte Blockierung. Mobile Proxys bieten die höchste Vertrauensstufe, sind jedoch teurer und langsamer.

Wie vermeide ich Blöcke bei der Implementierung?

Nutzen Sie Sticky Sessions für IP-Konsistenz, rotieren Sie über einen Pool von Sessions mit Promise.all, setzen Sie AbortController-Timeouts (z. B. 15 Sekunden) ein und implementieren Sie exponentielles Backoff bei 429/5xx-Antworten. Respektieren Sie Rate Limits und verwenden Sie Geo-Targeting, um Traffic aus dem erwarteten Land zu generieren.

Funktioniert das ProxyHat Node SDK unter Deno und Bun?

Ja. Das SDK ist reines JavaScript ohne native Abhängigkeiten und läuft unter Node.js, Deno und Bun. Es generiert die korrekte Proxy-URL mit Basic Auth und kann sowohl für HTTP (Port 8080) als auch SOCKS5 (Port 1080) konfiguriert werden.

Bereit loszulegen?

Zugang zu über 50 Mio. Residential-IPs in über 148 Ländern mit KI-gesteuerter Filterung.

Preise ansehenResidential Proxies
← Zurück zum Blog