Geliştirici Rehberleri6 dk okuma
curl ve Node.js ile proxy kullanımı: komut satırından koda
curl’de proxy tek bir seçenektir; Node.js’te ise yerleşik fetch proxy ortam değişkenlerini varsayılan olarak okumaz ve bir ajan ya da dağıtıcı (dispatcher) gerekir. Bu rehber ikisini de çalışır örneklerle anlatıyor.
Kısa cevap: curl’de -x http://PROXY_ADRESI:PORT --proxy-user KULLANICI:PAROLA; Node.js’te undici paketinin ProxyAgent sınıfı ya da node:https ile https-proxy-agent. Aşağıda önce curl’ün proxy ile ilgili seçeneklerini, zaman ölçümünü ve ortam değişkenlerini, ardından Node.js 20 ve üzeri için üç yaklaşımı ele alıyoruz. Farklı dillerde kısa bağlantı örnekleri Geliştirici sayfasında; Python için ayrıntılı rehber Python ile proxy kullanımı.
curl: temel kullanım
# HTTP proxy, kimlik bilgisi ayrı seçenekte
curl -x http://PROXY_ADRESI:PORT --proxy-user KULLANICI:PAROLA "https://api.ipify.org?format=json"
# Aynısı, kimlik bilgisi proxy URL’sinin içinde
curl -x "http://KULLANICI:PAROLA@PROXY_ADRESI:PORT" "https://api.ipify.org?format=json"
# SOCKS5, hedef adını proxy çözer
curl --socks5-hostname PROXY_ADRESI:PORT --proxy-user KULLANICI:PAROLA "https://api.ipify.org?format=json"
# Aynısı, URL biçimiyle
curl -x "socks5h://KULLANICI:PAROLA@PROXY_ADRESI:PORT" "https://api.ipify.org?format=json"- URL’yi tırnak içine alın.
?ve&kabukta özel anlam taşır; tırnaksız bir sorgu dizesi bölünebilir. - Windows PowerShell 5.1’de
curladıInvoke-WebRequestkomutunun takma adıdır; bu seçeneklerle gerçek curl’ü çalıştırmak içincurl.exeyazın. - Şema belirtilmezse
-xdeğeri HTTP proxy sayılır; port yazılmazsa curl 1080 varsayar. - HTTPS hedeflerde curl
CONNECTtünelini kendisi kurar. Düz HTTP hedeflerde de tünel istiyorsanız-p(--proxytunnel) ekleyin. - Paroladaki özel karakterler: curl, proxy URL’sindeki kullanıcı adı ve parolanın URL kodlamasını çözer;
@için%40,:için%3ayazabilirsiniz. --socks5ile--socks5-hostnamefarkı: ilki hedef adını yerelde çözer, ikincisi proxy’ye bırakır. Ayrıntı: DNS sızıntısı nedir?
Zaman aşımı ve ayrıntılı çıktı
curl -v --connect-timeout 5 --max-time 20 \
-x "http://KULLANICI:PAROLA@PROXY_ADRESI:PORT" \
"https://api.ipify.org?format=json"--connect-timeout yalnızca bağlantı aşamasını, --max-time ise bütün işlemi sınırlar. -v çıktısında CONNECT isteğini, proxy’nin yanıt kodunu ve ardından tünelin içindeki TLS el sıkışmasını görürsünüz; 407 yanıtı alıyorsanız sorun kimlik bilgisindedir. Ayrıntılı çıktı Proxy-Authorization başlığını içerebilir; paylaşmadan önce o satırı silin. Seçeneklerin tamamı curl kılavuzunda (yeni sekmede açılır).
-w ile bağlantının aşamalarını ölçmek
curl -s -o /dev/null \
-x "http://KULLANICI:PAROLA@PROXY_ADRESI:PORT" \
-w "dns: %{time_namelookup}\nconnect: %{time_connect}\ntls: %{time_appconnect}\nttfb: %{time_starttransfer}\ntotal: %{time_total}\ncode: %{http_code}\n" \
"https://api.ipify.org?format=json"| Değişken | Proxy kullanırken neyi ölçer? |
|---|---|
time_namelookup | Ad çözümlemesinin bittiği an. HTTP proxy’de hedef adını proxy çözdüğü için bu değer proxy’nin kendi adının çözümlenmesini yansıtır. |
time_connect | Proxy sunucusuna TCP bağlantısının kurulduğu an. |
time_appconnect | Hedefle TLS el sıkışmasının, tünelin içinden, tamamlandığı an. |
time_starttransfer | İlk yanıt baytının geldiği an; hedef sunucunun işlem süresini de içerir. |
time_total | İşlemin toplam süresi. |
Ortam değişkenleri ve NO_PROXY
export http_proxy="http://KULLANICI:PAROLA@PROXY_ADRESI:PORT"
export HTTPS_PROXY="http://KULLANICI:PAROLA@PROXY_ADRESI:PORT"
export NO_PROXY="localhost,127.0.0.1,.dahili.ornek"
curl "https://api.ipify.org?format=json"curl’de http_proxy yalnızca küçük harfle okunur
curl ortam değişkenlerini büyük ya da küçük harfle kabul eder ve küçük harfliye öncelik verir; tek istisna http_proxy’dir, yalnızca küçük harfle okunur. ALL_PROXY, şemaya özel bir değişken yoksa kullanılır. -x ortam değişkenlerini geçersiz kılar; NO_PROXY ise -x verilmiş olsa bile listedeki adlar için proxy’yi devre dışı bırakır. Windows ortam değişkenlerinde büyük-küçük harf ayrımı yapmaz.
Parolayı ortam değişkenine ya da komut satırına yazmak pratik ama iz bırakan bir yöntemdir: komut satırı kabuk geçmişine düşer, ortam değişkenleri alt işlemlere geçer. Tekrarlanan işlerde -K ile okunan, izinleri kısıtlanmış bir curl yapılandırma dosyası daha temizdir; örneği Proxy kimlik doğrulama rehberinde bulabilirsiniz.
Node.js: fetch neden proxy’yi görmüyor?
Node.js’in yerleşik fetch işlevi (Node.js belgeleri (yeni sekmede açılır)) undici üzerine kuruludur ve HTTP_PROXY, HTTPS_PROXY gibi ortam değişkenlerini varsayılan olarak kullanmaz; terminalde curl proxy’den çıkarken aynı makinedeki bir Node betiği doğrudan bağlanabilir. Daha yeni sürümlerde (Node.js 24.0.0 ve 22.21.0’dan itibaren) NODE_USE_ENV_PROXY=1 ortam değişkeniyle, 24.5.0 ve 22.21.0’dan itibaren --use-env-proxy bayrağıyla da, Node.js HTTP_PROXY, HTTPS_PROXY ve NO_PROXY değişkenlerine göre istekleri proxy’ye yönlendirebilir; belgeler bu özelliği “aktif geliştirme” aşamasında gösterir ve Node.js 20’de bu seçenek yoktur. Sürümden bağımsız çalışan yol, isteğe bir dağıtıcı (dispatcher) vermektir. En doğrudan yol, npm’deki undici paketinin ProxyAgent (yeni sekmede açılır) sınıfıdır. Örnekler ES modülüdür; dosyayı .mjs uzantısıyla kaydedin.
import { ProxyAgent, fetch } from 'undici';
const dispatcher = new ProxyAgent({
uri: 'http://PROXY_ADRESI:PORT',
token: 'Basic ' + Buffer.from('KULLANICI:PAROLA').toString('base64'),
});
try {
const res = await fetch('https://api.ipify.org?format=json', {
dispatcher,
signal: AbortSignal.timeout(20000),
});
console.log(res.status, await res.json());
} catch (err) {
console.error('İstek başarısız:', err.cause ?? err);
}- Sürüm uyumu: npm’deki güncel undici 8.x sürümü Node.js 22.19.0 veya üzerini ister. Node.js 20 kullanıyorsanız
npm install undici@7ile 7.x sürümünü kurun; 7.x de Node.js 20.18.1 veya üzerini ister. Bu örnektekiProxyAgent,tokenvefetchiki sürümde de vardır. token, proxy’ye gönderilecekProxy-Authorizationdeğeridir. Kullanıcı adı ve parolayıhttp://KULLANICI:PAROLA@PROXY_ADRESI:PORTbiçiminde URL içine yazmak da desteklenir.- HTTPS hedeflerde ProxyAgent
CONNECTtüneli kurar; tünel kurulamazsa hata fırlatılır. fetch hatalarında asıl neden çoğunluklaerr.causeiçindedir. - Bütün istekleri proxy’den geçirmek için
setGlobalDispatcher(new ProxyAgent(…))kullanılabilir. Yerleşik fetch ile npm’deki undici sürümü arasındaki uyumsuzluklardan kaçınmak için örnektefetch’i de undici paketinden alıyoruz. - Ortam değişkenlerini okuyan bir dağıtıcı isterseniz undici’nin
EnvHttpProxyAgentsınıfıhttp_proxy,https_proxyveno_proxydeğişkenlerini (büyük harfli karşılıklarıyla birlikte) kullanır;ALL_PROXYbu listede yoktur.
node:https ve https-proxy-agent
import https from 'node:https';
import { HttpsProxyAgent } from 'https-proxy-agent';
const agent = new HttpsProxyAgent('http://KULLANICI:PAROLA@PROXY_ADRESI:PORT');
const req = https.get('https://api.ipify.org?format=json', { agent, timeout: 20000 }, (res) => {
let body = '';
res.setEncoding('utf8');
res.on('data', (chunk) => {
body += chunk;
});
res.on('end', () => console.log(res.statusCode, body));
});
req.on('timeout', () => req.destroy(new Error('Zaman aşımı')));
req.on('error', (err) => console.error('Hata:', err.message));HttpsProxyAgent, HTTPS hedefler için CONNECT tüneli kurar ve URL’deki kimlik bilgilerinden Proxy-Authorization başlığını üretir. Düz HTTP hedefler için aynı ailenin http-proxy-agent paketindeki HttpProxyAgent kullanılır. Bu ajanlar node:http / node:https tabanlı kütüphanelerle çalışır; ortam değişkenlerini kendileri okumaz. Güncel sürümleri (https-proxy-agent 9, http-proxy-agent 9, socks-proxy-agent 10) yalnızca ES modülü olarak dağıtılır ve Node.js 20 veya üzerini ister; require() yerine örneklerdeki gibi import kullanın.
SOCKS5: socks-proxy-agent
import https from 'node:https';
import { SocksProxyAgent } from 'socks-proxy-agent';
const agent = new SocksProxyAgent('socks5h://KULLANICI:PAROLA@PROXY_ADRESI:PORT');
const req = https.get('https://api.ipify.org?format=json', { agent, timeout: 20000 }, (res) => {
let body = '';
res.setEncoding('utf8');
res.on('data', (chunk) => {
body += chunk;
});
res.on('end', () => console.log(res.statusCode, body));
});
req.on('timeout', () => req.destroy(new Error('Zaman aşımı')));
req.on('error', (err) => console.error('Hata:', err.message));socks-proxy-agent’ta da şema DNS davranışını belirler: socks5h:// hedef adını proxy’ye bırakır, socks5:// yerelde çözer. SOCKS5 kimlik doğrulaması RFC 1929’a göre açık metin gider; ayrıntılar Proxy kimlik doğrulama rehberinde. SOCKS5’in hangi paketlerde seçilebildiğini HTTP & SOCKS5 Proxy sayfasında görebilirsiniz.
Node.js’te zaman aşımı ve hata ayıklama
Yerleşik ya da undici fetch kullanırken süreyi AbortSignal.timeout(ms) ile sınırlayın; süre dolduğunda istek, adı TimeoutError olan bir hatayla reddedilir. Ağ katmanındaki hatalarda fetch genel bir TypeError: fetch failed mesajı verir; işe yarayan bilgi err.cause içindedir. Orada çoğunlukla ECONNREFUSED (proxy portu kapalı ya da adres yanlış), ENOTFOUND (proxy’nin adı çözülemedi) veya undici’ye özgü UND_ERR_ önekli kodlar görürsünüz. node:https örneklerinde timeout seçeneği soket hareketsiz kaldığında timeout olayını tetikler; isteği kendiniz sonlandırmanız gerekir, örnekteki req.destroy(…) bunu yapar.
Sorunun proxy’de mi kodda mı olduğunu ayırmanın en hızlı yolu aynı proxy’yi önce curl ile denemektir. curl -v ile çalışıyor ama Node betiği çalışmıyorsa sorun büyük olasılıkla ajan, dağıtıcı ya da URL yazımındadır; ikisi de çalışmıyorsa proxy adresini, portu ve kimlik bilgilerini kontrol edin. Her iki aracın aynı test adresinde aynı çıkış adresini göstermesi, yapılandırmanın tutarlı olduğunun iyi bir işaretidir.
Sık görülen sorunlar
| Belirti | Olası neden |
|---|---|
| curl proxy’den çıkıyor, Node betiği gerçek adresinizi gösteriyor | Yerleşik fetch ortam değişkenlerini okumuyor; dağıtıcı ya da ajan verilmedi. |
HTTP_PROXY tanımlı ama curl düz HTTP isteklerde kullanmıyor | curl bu değişkeni yalnızca küçük harfle (http_proxy) okur. |
| curl ile 407 | Kimlik bilgisi eksik veya hatalı; paroladaki özel karakterler kodlanmamış olabilir. |
fetch fetch failed hatası veriyor | Gerçek neden err.cause içindedir: bağlantı reddi, zaman aşımı ya da tünel kurulamaması. |
| SOCKS5 ile bağlanıyor ama yerel DNS sorgusu görülüyor | Şema socks5:// yazılmış; socks5h:// kullanın. |
Özet: hangi araçta ne kullanılır?
| Araç | HTTP proxy | SOCKS5 | Ortam değişkenleri |
|---|---|---|---|
| curl | -x http://… ve --proxy-user | --socks5-hostname veya socks5h:// | Okunur; http_proxy yalnızca küçük harf |
| Node.js, undici fetch | ProxyAgent ile dispatcher | Bu rehberde node:https + socks-proxy-agent | EnvHttpProxyAgent ile |
Node.js, node:https | https-proxy-agent | socks-proxy-agent | Ajan kendisi okumaz |
Kod yazmadan önce proxy’nin canlı olup olmadığını ve hangi adresten çıktığını görmek isterseniz Proxy Kontrol aracını, CONNECT tünelinin doğru çalışıp çalışmadığını görmek için HTTP Proxy Kontrol aracını kullanabilirsiniz.
Sık sorulanlar