- Yayın tarihi
- Okuma süresi
- 3 dk okuma
Node.js ile Proxy Kullanımı: undici ve fetch
Node.js 20 ve 22'de fetch, undici ProxyAgent, https modülü ile CONNECT ve socks-proxy-agent kullanımı; kimlik doğrulama, zaman aşımı ve hata ayıklama örnekleriyle.
Node.js'te proxy kullanımı, hangi HTTP istemcisini seçtiğinize göre değişir. Yerleşik fetch proxy'yi kendiliğinden bilmez, https modülü ise yalnızca ayrı bir CONNECT isteğiyle çalışır. Bu rehber Node 20 ve 22 için üç yolu, çalışan örnekleriyle anlatır.
Örnekler ES modülü biçimindedir; dosyaları .mjs uzantısıyla kaydedin ya da package.json içine "type": "module" ekleyin. PROXY_HOST, PROXY_PORT, KULLANICI ve PAROLA yer tutucudur. Komutlar Windows ve Linux'ta aynıdır; fark yalnızca ortam değişkeni söz diziminde çıkar (aşağıda).
Hazırlık
node --version
npm init -y
npm i undiciKimlik bilgisini kodun içine gömmeyin. Ortam değişkenlerinden okuyun:
# Linux ve macOS
export PROXY_HOST="PROXY_HOST" PROXY_PORT="PROXY_PORT"
export PROXY_USER="KULLANICI" PROXY_PASS="PAROLA"# Windows PowerShell
$env:PROXY_HOST = "PROXY_HOST"; $env:PROXY_PORT = "PROXY_PORT"
$env:PROXY_USER = "KULLANICI"; $env:PROXY_PASS = "PAROLA"1. undici ProxyAgent ile fetch
Node'un küresel fetch işlevi undici üzerine kuruludur. Proxy için ProxyAgent oluşturup dispatcher olarak verirsiniz. Kimlik doğrulamayı token seçeneğiyle, Basic başlığını kendiniz üreterek yapmak parola kodlama sorununu önler.
// proxy-fetch.mjs
import { fetch, ProxyAgent } from 'undici';
const { PROXY_HOST, PROXY_PORT, PROXY_USER, PROXY_PASS } = process.env;
const dispatcher = new ProxyAgent({
uri: `http://${PROXY_HOST}:${PROXY_PORT}`,
token: 'Basic ' +
Buffer.from(`${PROXY_USER}:${PROXY_PASS}`).toString('base64'),
});
const res = await fetch('https://api64.ipify.org', {
dispatcher,
signal: AbortSignal.timeout(15_000),
});
console.log(res.status, await res.text());Çalıştırma: node proxy-fetch.mjs. Çıktıda proxy çıkış adresini görmelisiniz. api64.ipify.org hem IPv4 hem IPv6 ile erişilebilen bir adres yansıtma hizmetidir; sonuç IPv6 ise trafik IPv6'dan çıkıyordur.
Burada fetch işlevini doğrudan undici paketinden içe aktarmak bilinçli bir seçimdir. Node'un yerleşik fetch'i kendi içindeki undici sürümünü kullanır; npm'den kurduğunuz ProxyAgent başka bir sürümse, ikisini karıştırmak beklenmedik hatalara yol açabilir. Aynı paketten ikisini birlikte almak bu riski kaldırır.
Tüm istekler için küresel proxy
Her fetch çağrısına dispatcher yazmak istemiyorsanız küresel yönlendirici ayarlayın:
import { fetch, ProxyAgent, setGlobalDispatcher } from 'undici';
setGlobalDispatcher(new ProxyAgent(
`http://${process.env.PROXY_HOST}:${process.env.PROXY_PORT}`
));Küresel ayar bütün isteklerin proxy'den geçmesine yol açar; yerel servislere ya da başka API'lere giden istekleri de etkiler. Karışık kullanımda istek başına dispatcher vermek daha öngörülebilirdir.
Ortam değişkeninden okumak
Node çekirdeği HTTP_PROXY ve HTTPS_PROXY değişkenlerini varsayılan olarak okumaz; ayarlamanız yeterli olmaz. undici'nin yeni sürümleri bu iş için EnvHttpProxyAgent sunar:
import { fetch, EnvHttpProxyAgent } from 'undici';
const dispatcher = new EnvHttpProxyAgent(); // HTTP_PROXY, HTTPS_PROXY, NO_PROXY
const res = await fetch('https://example.com', { dispatcher });
console.log(res.status);Yeni Node sürümlerinde ortam değişkenine yerleşik destek eklenmiş olabilir. Hangi sürümde nasıl çalıştığı için kullandığınız sürümün belgesine bakın; üretim kodunda davranışı sürüme bırakmayıp dispatcher ile açıkça belirtmeniz daha güvenlidir.
2. https modülü ile elle CONNECT
Bir HTTP proxy üzerinden HTTPS hedefe gitmek için önce proxy'ye CONNECT isteği gönderilir, tünel açıldıktan sonra TLS bu tünelin içinde kurulur (RFC 9110 §9.3.6 (yeni sekmede açılır)). CONNECT isteğinde hedef host:port biçimindedir ve port zorunludur. Aşağıdaki kod bunu kütüphanesiz yapar; proxy'nin ne yaptığını anlamak için iyi bir araçtır.
// connect.mjs
import http from 'node:http';
import https from 'node:https';
const { PROXY_HOST, PROXY_PORT, PROXY_USER, PROXY_PASS } = process.env;
const hedef = 'api64.ipify.org';
const auth = Buffer.from(`${PROXY_USER}:${PROXY_PASS}`).toString('base64');
const req = http.request({
host: PROXY_HOST,
port: Number(PROXY_PORT),
method: 'CONNECT',
path: `${hedef}:443`,
headers: { 'Proxy-Authorization': `Basic ${auth}`, Host: `${hedef}:443` },
timeout: 10_000,
});
req.on('connect', (res, socket) => {
if (res.statusCode !== 200) {
console.error('CONNECT başarısız:', res.statusCode);
socket.destroy();
return;
}
https.get({ host: hedef, path: '/', socket, agent: false }, (r) => {
let govde = '';
r.on('data', (d) => (govde += d));
r.on('end', () => console.log(r.statusCode, govde));
}).on('error', (e) => console.error('TLS/İstek hatası:', e.message));
});
req.on('timeout', () => req.destroy(new Error('CONNECT zaman aşımı')));
req.on('error', (e) => console.error('Proxy hatası:', e.message));
req.end();Proxy 407 dönerse kimlik bilgisi yanlıştır, 502 dönerse proxy hedefe ulaşamamıştır. Bu kodların cURL'deki karşılıkları ve ayırt etme yöntemi cURL ile proxy testi yazısında tablo halindedir. IPv6 proxy adresi kullanıyorsanız host alanına köşeli parantezsiz yazın (2001:db8::1); köşeli parantez yalnızca URL içinde gerekir.
3. SOCKS5 için socks-proxy-agent
undici ProxyAgent yalnızca HTTP/HTTPS proxy ile tünel açar. SOCKS5 için socks-proxy-agent paketini http ve https modülleriyle birlikte kullanabilirsiniz.
npm i socks-proxy-agent// socks.mjs
import https from 'node:https';
import { SocksProxyAgent } from 'socks-proxy-agent';
const { PROXY_HOST, PROXY_PORT, PROXY_USER, PROXY_PASS } = process.env;
const user = encodeURIComponent(PROXY_USER);
const pass = encodeURIComponent(PROXY_PASS);
const agent = new SocksProxyAgent(
`socks5h://${user}:${pass}@${PROXY_HOST}:${PROXY_PORT}`
);
https.get('https://api64.ipify.org', { agent, timeout: 15_000 }, (res) => {
let govde = '';
res.on('data', (d) => (govde += d));
res.on('end', () => console.log(res.statusCode, govde));
}).on('error', (e) => console.error(e.message));socks5h şemasıyla alan adı çözümü proxy'ye bırakılır. SOCKS5 protokolü RFC 1928 (yeni sekmede açılır) ve kullanıcı adı/parola doğrulaması RFC 1929 (yeni sekmede açılır) ile tanımlıdır; parola ağda düz metin taşınır.
SOCKS5 kodu yazmadan önce ürünün bu protokolü sunduğundan emin olun. IPv6 Proxy paket özelliklerinde protokol HTTP(S) olarak geçer, SOCKS5 listelenmemiştir; gerekiyorsa siparişten önce destekten sorun. Bağlantının SOCKS5 konuşup konuşmadığını SOCKS5 kontrol aracıyla sınayabilirsiniz.
Hata ayıklama
fetch failed iletisi tek başına işe yaramaz. Asıl neden cause alanındadır.
try {
const res = await fetch('https://example.com', {
dispatcher,
signal: AbortSignal.timeout(10_000),
});
console.log(res.status);
} catch (err) {
console.error('İleti:', err.message);
console.error('Neden:', err.cause?.code, err.cause?.message);
if (err.name === 'TimeoutError') console.error('Zaman aşımı doldu');
}| Belirti | Olası neden |
|---|---|
ECONNREFUSED | Proxy adresi ya da port yanlış, servis kapalı |
ETIMEDOUT, UND_ERR_CONNECT_TIMEOUT | Proxy'ye ağdan ulaşılamıyor, güvenlik duvarı |
ENOTFOUND | Proxy ya da hedef alan adı çözülemedi |
İletide 407 | Kimlik bilgisi yanlış ya da eksik |
İletide 502 veya tünel hatası | Proxy hedefe ulaşamadı |
TimeoutError | AbortSignal.timeout süresi doldu |
undici, tünel kurulamadığında proxy'nin döndüğü durum koduyla bir hata fırlatır (ileti, tünelin 200 yerine başka bir kod döndürdüğünü söyler). Hata ayıklamayı hızlandırmak için önce aynı bağlantıyı HTTP proxy kontrol aracıyla ya da cURL ile deneyin; sorun kodunuzda mı, proxy bilgilerinde mi olduğunu ayırt edersiniz.
Hedef yalnızca IPv4 yayın yapıyorsa fetch failed hatasının nedeni kodunuz değil adres ailesi olabilir: IPv6 çıkışlı bir proxy ona doğrudan bağlanamaz ve NAT64/DNS64 çevirisi gerekir. IPv6 Proxy sayfası böyle bir katmandan söz eder, ancak kapsamı doğrulanamamıştır; hedefinizi önceden deneyin.
Zaman aşımı ve eşzamanlılık
- Her istekte
AbortSignal.timeout(ms)kullanın; zaman aşımsız istek süreci sonsuza dek açık tutabilir. - Eşzamanlı istek sayısını sınırlayın. Aynı anda yüzlerce istek hem proxy'yi hem hedefi zorlar.
- Hata alan isteği hemen tekrarlamayın; artan bekleme süresiyle (üstel geri çekilme) birkaç kez deneyin.
- Kimlik bilgisini ortam değişkeninde ya da gizli bilgi yöneticisinde tutun, depoya göndermeyin.
Veri toplama gibi işlerde yasalara ve hedef sitenin kullanım koşullarına uyum sizin sorumluluğunuzdadır; yalnızca kamuya açık veriyle ve ölçülü hızla çalışın. Kullanım bağlamı için web scraping çözümü sayfasına, Python karşılığı için Python ile proxy kullanımı yazısına bakabilirsiniz.
Sık sorulan sorular
Node.js'in yerleşik fetch'i proxy kullanır mı?
Yerleşik fetch kendiliğinden proxy ayarı uygulamaz; proxy için undici'nin ProxyAgent nesnesini dispatcher olarak vermeniz gerekir. Yeni Node sürümlerinde ortam değişkeniyle yerleşik destek gelmiş olabilir, kullandığınız sürümün belgesine bakın.
Kimlik bilgisini proxy adresine mi yazmalıyım, token olarak mı vermeliyim?
İkisi de çalışır, ancak token seçeneğine Basic başlığını kendiniz üretmek özel karakterli parolalarda yüzde kodlaması derdini ortadan kaldırır. Parolayı kaynak koda değil ortam değişkenine koyun.
undici ile SOCKS5 proxy kullanabilir miyim?
undici ProxyAgent yalnızca HTTP/HTTPS proxy ile tünel açar. SOCKS5 için socks-proxy-agent paketini https modülüyle birlikte kullanabilirsiniz.
fetch failed hatasının nedeni nasıl bulunur?
İletinin kendisi bilgi vermez; asıl neden error.cause içindedir. cause.code değeri (ECONNREFUSED, ETIMEDOUT, UND_ERR_CONNECT_TIMEOUT gibi) sorunun adres, ağ ya da zaman aşımı olduğunu söyler.
/112İlgili sayfalar
- RehberPython ile Proxy Kullanımı: requests ve httpxPython'da requests ve httpx ile proxy kullanımı: kimlik doğrulama, özel karakterli parola, oturum, zaman aşımı, SOCKS5…
- RehbercURL ile Proxy Testi ve Sorun GidermecURL ile proxy nasıl test edilir: -x, kimlik doğrulama, socks5 ve socks5h, -v ile CONNECT gözlemi, zaman aşımı, IPv6…
- AraçHTTP Proxy KontrolHTTP/HTTPS proxy yanıtını ve gecikmesini ölçer
- AraçSOCKS5 KontrolSOCKS5 el sıkışmasını ve yetkilendirmeyi sınar
/128Ürün
IPv6 Proxy ürününü inceleyin
Adet bazlı fiyatlanan IPv6 proxy paketleri. Satışı Sağlam Proxy (saglamproxy.com) üzerinden yapılır.