Wer Proxies in Deno und Bun nutzen möchte, stößt schnell auf eine Überraschung: die eingebaute fetch()-Funktion ignoriert Proxy-Einstellungen standardmäßig komplett. Weder HTTP_PROXY-Umgebungsvariablen noch System-Proxies werden automatisch berücksichtigt. Dieser Leitfaden zeigt, wie Sie Denos Deno.createHttpClient und Buns nativen proxy-Parameter korrekt einsetzen, Geo-Targeting und Sticky Sessions in den Benutzernamen kodieren und Residential Proxies für blockierungsanfällige Ziele rotieren.
Warum fetch() Proxies ignoriert und wie Deno und Bun das Problem lösen
Die WHATWG fetch-Spezifikation definiert keinen Proxy-Parameter. Die Standard-fetch()-Signatur akzeptiert nur Request-Optionen wie headers, method oder signal — aber keinen Proxy. Das ist bewusst so festgelegt: Browser delegieren Proxy-Auflösung an das Betriebssystem oder die Netzwerkschicht. Server-seitige JavaScript-Runtimes haben diese Lücke unterschiedlich geschlossen.
Laut der MDN-Dokumentation zu fetch gibt es keinen Proxy-Parameter im Standard. Node.js benötigt Bibliotheken wie undici mit ProxyAgent. Deno und Bun gehen andere Wege, die direkter in die Runtime integriert sind.
Deno: Deno.createHttpClient mit Proxy-Konfiguration
In Deno erstellen Sie einen HTTP-Client mit Deno.createHttpClient() und übergeben ihn als client-Option an fetch. Der Client akzeptiert ein proxy-Objekt mit url und basicAuth:
// Deno: Proxy über createHttpClient
const client = Deno.createHttpClient({
proxy: {
url: "http://gate.proxyhat.com:8080",
basicAuth: {
username: "user-country-US-session-abc123",
password: "pass",
},
},
});
const res = await fetch("https://httpbin.org/ip", { client });
const body = await res.text();
console.log(body);
Der client ist wiederverwendbar — Sie können ihn für mehrere fetch-Aufrufe nutzen und so Verbindungen poolen. Das ist bei hohem Request-Volumen wichtig, da der TLS-Handshake sonst bei jedem Request neu erfolgt.
Bun: fetch mit proxy-Option
Bun macht es noch einfacher. Die fetch-Implementierung akzeptiert direkt einen proxy-Parameter als String oder URL-Objekt:
// Bun: Proxy direkt in fetch
const res = await fetch("https://httpbin.org/ip", {
proxy: "http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080",
});
const body = await res.text();
console.log(body);
Diese Einzeiler-Lösung ist ideal für schnelle Skripte. Für komplexere Szenarien mit Connection-Pooling oder Custom-CA-Zertifikaten empfiehlt sich jedoch eine zentralere Konfiguration.
Geo-Targeting und Sticky Sessions im Benutzernamen kodieren
ProxyHat kodiert Geo-Targeting und Session-Steuerung direkt im Benutzernamen. Das funktioniert mit allen Proxy-Typen — Residential, Mobile und Datacenter. Die Syntax ist einfach:
user-country-US— USA als Ziellanduser-country-DE-city-berlin— Berlin, Deutschlanduser-session-abc123— Sticky Session mit IDabc123user-country-US-session-abc123— Kombination aus Land und Session
Sticky Sessions halten dieselbe IP für die Dauer der Session aufrecht. Das ist wichtig, wenn eine Website Cookies oder IP-basierte Sessions erwartet — etwa bei Login-Flows oder mehrstufigen Formularen.
SOCKS5 auf Port 1080
Für SOCKS5-Verbindungen nutzen Sie Port 1080 statt 8080. In Deno sieht das so aus:
// Deno: SOCKS5-Proxy
const client = Deno.createHttpClient({
proxy: {
url: "socks5://gate.proxyhat.com:1080",
basicAuth: {
username: "user-country-DE-session-mySession",
password: "pass",
},
},
});
const res = await fetch("https://httpbin.org/ip", { client });
console.log(await res.text());
In Bun ersetzen Sie einfach die Proxy-URL:
// Bun: SOCKS5-Proxy
const res = await fetch("https://httpbin.org/ip", {
proxy: "socks5://user-country-DE-session-mySession:pass@gate.proxyhat.com:1080",
});
console.log(await res.text());
SOCKS5 ist nützlich, wenn Sie nicht-HTTP-Traffic tunneln oder wenn bestimmte Ziel-Server HTTP-Connect-Proxies erkennen und blockieren.
HTTP_PROXY- und HTTPS_PROXY-Umgebungsvariablen
Beide Runtimes unterstützen HTTP_PROXY und HTTPS_PROXY als Umgebungsvariablen, allerdings mit Einschränkungen. In Deno werden diese Variablen nur berücksichtigt, wenn kein expliziter client übergeben wird. In Bun können Sie BUN_CONFIG_PROXY setzen.
# Umgebungsvariablen setzen
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-Skript ausführen
deno run --allow-net script.ts
Wann sollten Sie Umgebungsvariablen nutzen und wann per-Client-Konfiguration? Die Faustregel:
- Umgebungsvariablen für einfache Skripte, CI/CD-Pipelines und wenn alle Requests denselben Proxy nutzen sollen.
- Per-Client-Konfiguration bei Multi-Proxy-Setups, Session-Rotation, verschiedenen Geo-Targets pro Request und wenn Sie unterschiedliche Proxy-Typen mischen.
Für Produktionssysteme mit mehreren gleichzeitigen Sessions ist die per-Client-Konfiguration fast immer die bessere Wahl — sie gibt Ihnen Kontrolle über Connection-Pooling, Timeouts und Retry-Logik pro Session.
Residential Proxies für blockierungsanfällige Ziele
Datacenter-IPs werden von vielen Websites blockiert, weil sie aus bekannten Rechenzentrums-Blöcken stammen. Laut einer Studie von Imperva zum Bot-Traffic machen Bots über 40 % des Internet-Traffics aus, und Anti-Bot-Systeme werden zunehmend aggressiver. Residential Proxies verwenden IPs, die echten Haushalten zugewiesen sind, und sind daher deutlich schwerer zu erkennen.
Für SERP-Tracking, Preisüberwachung und Social-Media-Research sind Residential Proxies die Standardwahl. Die Erfolgsquote liegt typischerweise bei 90–99 %, verglichen mit 40–60 % bei Datacenter-Proxies an blockierungsanfälligen Zielen.
Beispiel: Pool von Sticky Sessions rotieren
Das folgende Beispiel zeigt, wie Sie mehrere Sticky Sessions parallel ausführen — mit Promise.all für Concurrency und AbortController für Timeouts:
// Deno: Sticky-Session-Pool mit Timeout und Concurrency
interface FetchResult {
session: string;
status: number;
body: string;
durationMs: number;
}
async function fetchWithSession(
url: string,
sessionId: string,
country: string,
timeoutMs = 10000
): Promise<FetchResult> {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), timeoutMs);
const client = Deno.createHttpClient({
proxy: {
url: "http://gate.proxyhat.com:8080",
basicAuth: {
username: `user-country-${country}-session-${sessionId}`,
password: "pass",
},
},
});
const start = performance.now();
try {
const res = await fetch(url, { client, signal: controller.signal });
const body = await res.text();
return {
session: sessionId,
status: res.status,
body,
durationMs: Math.round(performance.now() - start),
};
} catch (err) {
if (err instanceof DOMException && err.name === "AbortError") {
console.error(`Session ${sessionId} timed out after ${timeoutMs}ms`);
} else {
console.error(`Session ${sessionId} failed:`, err.message);
}
return { session: sessionId, status: 0, body: "", durationMs: 0 };
} finally {
clearTimeout(timeout);
}
}
// 10 parallele Sessions
const sessions = Array.from({ length: 10 }, (_, i) => `sess-${i}-${Date.now()}`);
const target = "https://httpbin.org/ip";
const results = await Promise.all(
sessions.map((s) => fetchWithSession(target, s, "US"))
);
for (const r of results) {
console.log(`[${r.session}] ${r.status} in ${r.durationMs}ms`);
}
Dieses Muster skaliert gut bis etwa 50–100 gleichzeitige Sessions. Darüber hinaus sollten Sie einen Concurrency-Limiter wie p-limit oder eine Queue einsetzen, um die Ziel-Server nicht zu überlasten und Rate-Limits zu respektieren.
Produktionstipps: Retries, Custom CAs und Connection-Reuse
Retries mit exponentiellem Backoff
// Bun: Fetch mit Retry und Backoff
async function fetchWithRetry(
url: string,
proxy: string,
maxRetries = 3,
baseDelayMs = 500
): Promise<Response> {
let lastError: Error | null = null;
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
const res = await fetch(url, { proxy });
// Nur bei 5xx oder 429 retry
if (res.status >= 500 || res.status === 429) {
throw new Error(`HTTP ${res.status}`);
}
return res;
} catch (err) {
lastError = err as Error;
if (attempt < maxRetries) {
const delay = baseDelayMs * Math.pow(2, attempt);
const jitter = Math.random() * 100;
console.error(`Attempt ${attempt + 1} failed, retrying in ${Math.round(delay + jitter)}ms`);
await Bun.sleep(delay + jitter);
}
}
}
throw lastError;
}
const res = await fetchWithRetry(
"https://httpbin.org/ip",
"http://user-country-US-session-r1:pass@gate.proxyhat.com:8080"
);
console.log(await res.text());
Custom CA-Zertifikate in Deno
Wenn Ihr Ziel-Server ein selbstsigniertes Zertifikat verwendet, können Sie mit caCerts in Deno.createHttpClient vertraute Zertifikate angeben:
// Deno: Custom CA-Zertifikate
const caCert = await Deno.readTextFile("./my-ca.pem");
const client = Deno.createHttpClient({
proxy: {
url: "http://gate.proxyhat.com:8080",
basicAuth: {
username: "user-country-DE-session-ca-test",
password: "pass",
},
},
caCerts: [caCert],
});
const res = await fetch("https://internal.example.com/api", { client });
console.log(await res.text());
Connection-Reuse durch Client-Pooling
Erstellen Sie einen HttpClient pro Session und wiederverwenden Sie ihn für alle Requests dieser Session. Das spart TLS-Handshake-Zeit — typischerweise 100–300 ms pro Verbindung. Bei 1000 Requests pro Session sind das Minuten an gesparten Latenz.
// Deno: Client-Pool für wiederverwendbare Sessions
class ProxySessionPool {
private clients = new Map<string, Deno.HttpClient>();
getClient(sessionId: string, country = "US"): Deno.HttpClient {
if (!this.clients.has(sessionId)) {
const client = Deno.createHttpClient({
proxy: {
url: "http://gate.proxyhat.com:8080",
basicAuth: {
username: `user-country-${country}-session-${sessionId}`,
password: "pass",
},
},
});
this.clients.set(sessionId, client);
}
return this.clients.get(sessionId)!;
}
closeAll(): void {
for (const client of this.clients.values()) {
client.close();
}
this.clients.clear();
}
}
const pool = new ProxySessionPool();
// Verwendung
const client = pool.getClient("order-flow-123", "DE");
const res = await fetch("https://httpbin.org/ip", { client });
console.log(await res.text());
// Am Ende: pool.closeAll();
ProxyHat Node SDK: Side-by-Side mit nativem fetch
Das ProxyHat SDK läuft unter Node.js, Deno und Bun. Es abstrahiert Proxy-Verwaltung, Rotation und Session-Handling. Hier ist ein direkter Vergleich:
| Ansatz | Vorteile | Nachteile |
|---|---|---|
| Natives Deno fetch + createHttpClient | Keine Abhängigkeiten, volle Kontrolle, maximale Performance | Manuelle Session-Verwaltung, mehr Boilerplate |
| Natives Bun fetch mit proxy | Einfachste API, eine Zeile pro Request | Kein Connection-Pooling auf Client-Ebene |
| ProxyHat Node SDK | Eingebaute Rotation, automatische Retries, einheitliche API | Zusätzliche Abhängigkeit, weniger Low-Level-Kontrolle |
Beispiel mit dem SDK (läuft in Deno und Bun gleichermaßen): ProxyHat-Preise und verfügbare Standorte finden Sie im Dashboard.
// ProxyHat SDK in Deno/Bun
import { ProxyHat } from "proxyhat-sdk";
const ph = new ProxyHat({
username: "user",
password: "pass",
defaultCountry: "US",
});
// Automatische Rotation pro Request
const res1 = await ph.fetch("https://httpbin.org/ip");
console.log(await res1.text());
// Sticky Session
const res2 = await ph.fetch("https://httpbin.org/ip", {
session: "checkout-flow-42",
country: "DE",
});
console.log(await res2.text());
Ethisches Scraping: CFAA, GDPR und offizielle APIs
Bevor Sie Proxies für Web-Scraping einsetzen, prüfen Sie die rechtlichen Rahmenbedingungen. In den USA regelt der Computer Fraud and Abuse Act (CFAA) den Zugriff auf Computersysteme. Das Scraping öffentlicher Daten wurde in Fällen wie hiQ Labs v. LinkedIn als legal eingestuft, aber ToS-Verstöße können zivilrechtliche Konsequenzen haben.
In der EU gilt die DSGVO (GDPR). Personenbezogene Daten dürfen nur mit Rechtsgrundlage verarbeitet werden. Das Scrapen öffentlicher Profile kann personenbezogene Daten umfassen — hier ist juristischer Rat ratsam.
Best Practices für ethisches Scraping:
- Prüfen Sie zuerst offizielle APIs. Viele Plattformen bieten APIs an, die zuverlässiger und legaler sind als Scraping.
- Respektieren Sie robots.txt. Die Datei gibt an, welche Bereiche gecrawlt werden dürfen.
- Rate-Limits einhalten. Auch wenn kein explizites Limit existiert: überlasten Sie Ziel-Server nicht.
- Nur öffentliche Daten scrapen. Keine Login-geschützten Inhalte ohne Erlaubnis.
- DSGVO-konform handeln. Personenbezogene Daten nur mit Rechtsgrundlage verarbeiten.
Weitere Ressourcen: Web-Scraping-Anwendungsfälle und SERP-Tracking bei ProxyHat.
Key Takeaways
fetch()ignoriert Proxies standardmäßig — Deno nutztDeno.createHttpClient({ proxy }), Bun nutztfetch(url, { proxy }).- Geo-Targeting und Sticky Sessions werden im Benutzernamen kodiert:
user-country-US-session-abc123.- SOCKS5 läuft auf Port
1080, HTTP auf Port8080— beide übergate.proxyhat.com.- Residential Proxies erreichen 90–99 % Erfolgsquote an blockierungsanfälligen Zielen.
- Retries mit Backoff,
AbortController-Timeouts und Client-Pooling sind für Produktionssysteme essenziell.- Prüfen Sie immer zuerst offizielle APIs und respektieren Sie robots.txt, ToS und DSGVO.
Häufig gestellte Fragen
Was bedeutet die Nutzung von Proxies in Deno und Bun?
Es bezeichnet die Konfiguration von HTTP- oder SOCKS5-Proxies in den modernen JavaScript-Runtimes Deno und Bun. Da die Standard-fetch()-Funktion keine Proxy-Parameter unterstützt, nutzt Deno Deno.createHttpClient({ proxy }) und Bun den direkten proxy-Parameter in fetch(). Damit lassen sich Requests über Residential-, Mobile- oder Datacenter-Proxies routen.
Warum ist die Proxy-Nutzung in Deno und Bun wichtig?
Weil viele Websites Datacenter-IPs blockieren und fetch() nativ keine Proxies unterstützt. Ohne Proxy-Konfiguration schlagen Requests an blockierungsanfällige Ziele fehl. Mit Residential Proxies über ProxyHat erreichen Entwickler 90–99 % Erfolgsquote und können Geo-Targeting und Sticky Sessions für zuverlässiges Scraping und API-Zugriffe nutzen.
Welcher Proxy-Typ eignet sich am besten für Deno und Bun?
Für blockierungsanfällige Ziele wie SERP-Scraping oder Preisüberwachung sind Residential Proxies die beste Wahl, da sie echte Haushalts-IPs verwenden. Datacenter-Proxies sind schneller und günstiger, aber leichter zu erkennen. Mobile Proxies bieten die höchste Vertrauensstufe, sind aber teurer. Die Wahl hängt vom Use-Case ab — für die meisten Scraping-Aufgaben sind Residential Proxies der Kompromiss aus Erfolg und Kosten.
Wie vermeidet man Blockierungen bei der Proxy-Nutzung in Deno und Bun?
Nutzen Sie Sticky Sessions für mehrstufige Flows, rotieren Sie Sessions über einen Pool, setzen Sie Timeouts via AbortController ein und implementieren Sie Retries mit exponentiellem Backoff. Respektieren Sie Rate-Limits, kodieren Sie Geo-Targeting im Benutzernamen und kombinieren Sie Residential Proxies mit realistischen Headern und Request-Intervallen. Vermeiden Sie zu hohe Concurrency — 50–100 parallele Sessions sind ein guter Startpunkt.
Kann man das ProxyHat Node SDK in Deno und Bun verwenden?
Ja. Das ProxyHat SDK ist mit Node.js, Deno und Bun kompatibel. Es abstrahiert Proxy-Verwaltung, automatische Rotation und Session-Handling. Für maximale Kontrolle und Performance ohne Abhängigkeiten ist die native Konfiguration über Deno.createHttpClient oder Buns proxy-Parameter jedoch vorzuziehen.






