Geonode logo
Geonode Team

Geonode Team

Güncellenme: 7 Ekim 2026

Yayınlanma: 2 Eylül 2026

Node.js’de SuperAgent ile Proxy Nasıl Kullanılır?

SuperAgent’ta yerleşik bir proxy seçeneği bulunmamaktadır. Ya bir uzantı eklemeniz ya da bir HTTP aracısı sağlamanız gerekir; ancak her iki yaklaşım da bir isim çakışması nedeniyle karmaşıktır: SuperAgent’taki “`.agent()`” ifadesi zaten tamamen başka bir anlama gelmektedir. Bu çakışma, kullanıcıların bir proxy yapılandırdıklarını sanırken aslında bir çerez deposu yapılandırmış olmalarına yol açan özel bir kafa karışıklığına neden olmaktadır. Bu kılavuz, her iki yöntemi, ilgili terminolojiyi ve hangisinin gerçekten etkin olduğunu gösteren kontrolü ele almaktadır.

Biz Geonode olarak proxy satışı yapıyoruz; dolayısıyla bu kılavuz, ürünümüzü belirli bir istemciyle kullanmaya yönelik bir rehberdir. Geri kalanını atlasanız bile okumanız gereken satır şudur: Yapılandırma işleminden sonra çıkış adresini mutlaka doğrulayın; çünkü hiçbir işlev görmeyen bir proxy ayarı, hiçbir hata mesajı vermez. SuperAgent, isteğinizi memnuniyetle doğrudan iletecek, 200 yanıtı verecek ve proxy'nin atlandığını gösteren hiçbir işaret vermeyecektir. Doğrulama bölümü dört satırdan oluşur ve bu, bilmekle varsaymak arasındaki farktır.

Ayrıca, SuperAgent’ın tarayıcılarda da çalıştığını unutmayın; burada anlatılanların hiçbiri tarayıcılara uygulanmaz — bir tarayıcıya JavaScript’ten proxy kullanması söylenemez, bu nedenle burada anlatılan her şey yalnızca Node ile ilgilidir.

Terminoloji Sorunu

Öncelikle bu konuyu açıklığa kavuşturalım, çünkü bu durum ciddi hatalara yol açıyor.

SuperAgent’ta, argüman içermeyen .agent() komutu, çerezleri koruyan bir SuperAgent kopyası oluşturur. Kılavuz bu konuda açıkça şunu belirtir: "Node'da SuperAgent varsayılan olarak çerezleri kaydetmez, ancak .agent() yöntemini kullanarak çerezleri kaydeden bir SuperAgent kopyası oluşturabilirsiniz. Her kopyanın ayrı bir çerez deposu vardır."

const agent = request.agent();
await agent.post("/login").send({ user, pass });
await agent.get("/cookied-page");   // session cookie carried over

Bu ajanın da varsayılan ayarları vardır: "Ajan üzerinde çağrılan normal istek yöntemleri, o ajan tarafından yapılan tüm istekler için varsayılan olarak kullanılacaktır."

Öte yandan, bir argümanla birlikte çağrılan .agent(httpAgent) yöntemi, isteğe yönelik olarak Node'un http.Agent ayarını belirler; proxy desteği bu ayarda bulunur.

Aynı yöntem adı, birbiriyle ilgisi olmayan iki işlev; aradaki tek fark, bir argüman geçip geçmediğinizdir. Aynı oturumda hem SuperAgent ajansları hem de proxy ajansları hakkında bilgi edindiyseniz, herhangi bir şey yazmadan önce bu konuyu netleştirmeniz faydalı olacaktır.

Birinci Yöntem: Bir Proxy Aracısı

Tercih edilmesi gereken yaklaşım budur ve bunun nedeni bakım kolaylığıdır.

import request from "superagent";
import { HttpsProxyAgent } from "https-proxy-agent";

const agent = new HttpsProxyAgent("http://myuser:mypass@proxy.example.com:9000");

const res = await request
  .get("https://api.example.com/items")
  .agent(agent);

SOCKS için paketi şu şekilde değiştirin:

import { SocksProxyAgent } from "socks-proxy-agent";
const agent = new SocksProxyAgent("socks5h://proxy.example.com:1080");

socks5

yerine socks5h

adresine dikkat edin. h

varyantı, ana bilgisayar adlarını yerel olarak değil proxy üzerinden çözümler; bu da trafiğiniz başka bir yere giderken DNS sorgularının kendi çözümleyicinize gitmesini engeller — bu sızıntı, coğrafi konum belirleme amacıyla proxy kullanmanın amacını sessizce ortadan kaldırır.

Ayrıca proxy-agent

, URL'nin belirlediği protokolü işler; bu, proxy yapılandırmadan geldiğinde kullanışlıdır:

import { ProxyAgent } from "proxy-agent";
const agent = new ProxyAgent();   // reads http_proxy / https_proxy / no_proxy

Neden SuperAgent uzantısı yerine bu paketler: Üçü de aktif olarak güncellenmektedir. Eylül 2026’da npm kayıt defterinde kontrol edildiğinde, proxy-agent

sürüm 8.0.2, https-proxy-agent

sürüm 9.1.0 ve socks-proxy-agent

sürüm 10.1.0’dır; hepsi Haziran 2026’da yayınlanmıştır.

İkinci Yöntem: superagent-proxy

Bu amaç için özel olarak geliştirilmiş bir uzantı ve beraberinde gelen bir uyarı.

import request from "superagent";
import superagentProxy from "superagent-proxy";

superagentProxy(request);

const res = await request
  .get("https://api.example.com/items")
  .proxy("http://myuser:mypass@proxy.example.com:9000");

README dosyasında, bu uzantının “superagent’ın Request sınıfını .proxy(uri) işleviyle genişlettiği” belirtiliyor ve “proxy-agent modülü tarafından desteklendiği” ifade ediliyor.

API, bir ajanı aktarmaktan daha kullanışlıdır. .proxy(uri) çağrısı, komut zincirinde daha akıcıdır ve "HTTP, HTTPS veya SOCKS" URI'lerini kabul ederek protokol seçimini proxy-agent adresine devreder.

Dikkat edilmesi gereken nokta, sürüm tarihidir. superagent-proxy , Eylül 2021’de yayınlanan 3.0.0 sürümündedir — bu yazının yazıldığı tarihte yaklaşık beş yıllık bir sürümdür; oysa temelindeki proxy-agent bağımlılığı güncellenmeye devam etmiştir. Kullanımdan kaldırılmamıştır ve çalışmamaktadır, ancak sardığı şey değişirken kendisi değişmemiş ince bir sarmalayıcıdır.

Bunun pratikteki sonucu şudur: Eğer halihazırda kullanıyorsanız ve sorunsuz çalışıyorsa, acil bir durum söz konusu değildir. Yeni kodlar için, proxy ajanı doğrudan kullanmak sadece bir satırlık bir ekleme gerektirir ve bağımlılık ağacınızdan eskimiş bir katmanı ortadan kaldırır — ve bu uzantı tam da o ajanın etrafına sarılmış bir sarmalayıcı olduğundan, sadece sözdizimini kaybedersiniz.

Gerçekten Çalışıp Çalışmadığını Doğrulayın

En önemli dört satır.

const res = await request
  .get("https://api.ipify.org?format=json")
  .agent(agent);

console.log(res.body);

Bunu hem ajanı kullanarak hem de ajansız olarak çalıştırın. Adres değişmezse, proxy yolunda yer almıyor demektir. Bu durumda SuperAgent size herhangi bir hata, uyarı veya başarısız istek bildirmez — trafik doğrudan ilerler.

Bir yapılandırmanın genellikle hiçbir işe yaramamasının üç nedeni:

.agent()'i hiçbir argüman olmadan çağırdınız; bu da bir HTTP ajanı ayarlamak yerine SuperAgent'ın çerezlerde kalıcı bir kopyasını oluşturur. Bu, terminolojiyle ilgili bir tuzaktır ve tam olarak bu sorunu ortaya çıkarır.

Aracıyı yanlış isteğe uyguladınız. SuperAgent’ın zincirleme işlevi istek bazındadır; bu nedenle, bir çağrıda ayarlanan bir aracı bir sonraki çağrıya uygulanmaz. Tutarlı bir davranış için, istek oluşturmayı bir işlev içine alın.

Aracı türü hedefle eşleşmiyor. HttpsProxyAgent, HTTPS hedeflerini işler; düz HTTP hedefi için HTTP varyantı gerekebilir. proxy-agent, sizin yerinize seçim yaparak bu sorunu ortadan kaldırır.

Coğrafi hedeflemeli proxy'ler için adres kontrolü yeterli değildir. Sonuca göre doğrulayın — bölgelere göre gerçekten farklılık gösteren bir şey isteyin ve yanıtın değiştiğini teyit edin. API'niz kendi bölgenizin verilerini döndürürken bir arama hizmetinin doğru ülkeyi bildirmesi, hedeflemenin olması gereken yere ulaşmadığı anlamına gelir; bu da proxy'leri test etmenin neden önemli olduğu başlıklı yazımızda anlattığımız "sessiz hata" örneğidir.

Proxy Üzerinden Zaman Aşımları

SuperAgent’ın zaman aşımı modeli olağanüstü derecede iyidir ve bir proxy gecikmeye neden olduğunda bu özelliği doğru şekilde kullanmaya değer.

Kılavuzda iki ayar açıklanmaktadır. req.timeout({deadline: ms})

— ya da req.timeout(ms)

— “tüm isteğin (tüm yüklemeler, yönlendirmeler ve sunucu işleme süresi dahil) tamamlanması için bir son süre belirler. Yanıt bu süre içinde tamamen indirilmezse, istek iptal edilir." Ayrıca req.timeout({response: ms})

"sunucudan ilk baytın gelmesi için bekleme süresini belirler, ancak indirmenin tamamının ne kadar süreceğini sınırlamaz."

Belgelerde boyutlandırma konusunda verilen tavsiye, proxy üzerinden yapılan isteklerle doğrudan ilgilidir: "Yanıt zaman aşımı, sunucunun yanıt vermesi için gereken süreden en az birkaç saniye daha uzun olmalıdır; çünkü bu süre, DNS araması, TCP/IP ve TLS bağlantılarının kurulması ve istek verilerinin yüklenmesi için gereken süreyi de içerir."

Proxy üzerinden bu aşamaların her biri daha fazla zaman alır. Ev tipi çıkış noktası, istek başına gerçek gecikme ekler ve bu, bir arıza değil, mesafeyle ilgilidir.

const res = await request
  .get("https://api.example.com/items")
  .agent(agent)
  .timeout({ response: 15000, deadline: 60000 });

Belgeler her ikisinin de kullanılmasını önerir ve bunun nedeni her yerde olduğu gibidir: yanıt zaman aşımı, hiç yanıt vermeyen bir sunucuyu yakalarken, son tarih ise yanıt verdikten sonra yavaş yavaş veri gönderen bir sunucuyu yakalar. Hiçbiri tek başına her iki durumu da kapsamaz.

Değerleri alışkanlıklarınız yerine proxy üzerinden yapılan ölçümlere göre ayarlayın; aksi takdirde, bozuk bir proxy gibi görünen, ancak aslında hesaba katmadığınız gecikmelerden kaynaklanan hatalarla karşılaşırsınız.

Hata Yönetimi

SuperAgent’ın varsayılan davranışı çoğu istemciden farklıdır ve bu durum burada önemlidir.

Belgelerde şu husus açıkça belirtilmiştir: "SuperAgent, varsayılan olarak 4xx ve 5xx yanıtlarını (ayrıca işlenmemiş 3xx yanıtlarını da) hata olarak değerlendirir". Belgelerde ayrıca "bu durum bilgisi err.status adresi üzerinden erişilebilir" ve bu tür hataların "err.response alanını da içerdiği" belirtilmektedir.

Dolayısıyla, bir proxy kimlik doğrulama hatası, yanıt yerine bir reddetme olarak gelir:

try {
  const res = await request.get(url).agent(agent).timeout({ deadline: 30000 });
  return res.body;
} catch (err) {
  if (err.status === 407) throw new Error("Proxy rejected credentials");
  if (err.status === 401) throw new Error("Target requires authentication");
  if (!err.status) throw new Error(`Network error: ${err.code} ${err.message}`);
  throw err;
}

407 ile 401 arasındaki ayrımı dikkate almak önemlidir. 407 kodu, proxy'nin sizi durdurduğu ve hedefe asla ulaşılamadığı anlamına gelir; 401 kodu ise proxy'nin çalıştığı ve hedefin kimlik bilgilerini istediği anlamına gelir. Bunlar farklı durumlardır, farklı çözümleri gerektirir ve her ikisi de atılan hata olarak göründüğünde kolayca karıştırılabilirler.

err.status'su olmayan bir hata, hiçbir HTTP yanıtının ulaşmadığı anlamına gelir; bu da kimsenin kimlik doğrulamasından ziyade bağlantı sorununa işaret eder. ECONNREFUSED, proxy adresinde dinleyen bir şeyin olmadığı anlamına gelir; ETIMEDOUT ise paketlerin kaybolduğu anlamına gelir.

Bazı hata durumlarını başarı olarak değerlendirmek için — 404'ü bir hata yerine veri olarak okumak — .ok() kullanın:

.ok(res => res.status < 500)

Yeniden Denemeler: Dikkatli Olun

SuperAgent’ta yerleşik bir yeniden deneme özelliği bulunur; ancak bu özelliğin, dikkate alınması gereken ve belgelenmiş bir kısıtlaması vardır.

const res = await request.get(url).agent(agent).retry(2);

Belgelerde, .retry()'in "geçici bir hatadan veya dengesiz bir İnternet bağlantısından kaynaklanabilecek bir şekilde başarısız olan istekleri otomatik olarak yeniden deneyeceği" açıklanmaktadır; bu işlev, isteğe bağlı bir yeniden deneme sayısı (varsayılan 1) ve "her yeniden denemeden önce" çağrılan bir geri çağırma alır. Geri çağırma işlevi, "isteğin yeniden denenip denenmeyeceğini kontrol etmek içtrue/false değerlerini döndürebilir (ancak maksimum yeniden deneme sayısı her zaman uygulanır)".

Belgelerde açıkça belirtilen kısıtlama şudur: .retry() komutunu "yalnızca idempotent olan isteklerle" kullanın.

Proxy üzerinden bu durum, belirli bir nedenden ötürü her zamankinden daha önemlidir. Zaman aşımı, başarısızlığın kanıtı değildir — istek hedefe ulaşmış ve başarılı olmuş olabilir, ancak yanıt geri dönüş yolunda kaybolmuş olabilir. Bunun olabileceği ek bir geçiş noktası vardır. Bu durumda bir POST isteğini yeniden denemek, bir yazma işleminin iki kez gerçekleşmesine neden olabilir ve hiçbir yeniden deneme yapılandırması bunu güvenli hale getiremez. İşlemin önemli olduğu durumlarda, API sunuyorsa bir idempotency anahtarı kullanın.

Geri arama işlevi, kimlik doğrulama hatasının yeniden denenmesini önlemek için de doğru yerdir; çünkü yanlış kimlik bilgileriyle yapılan bir 407 hatası, her denemede 407 hatası üretecektir:

.retry(3, (err, res) => {
  if (res?.status === 407 || res?.status === 401) return false;
  return true;
})

Yazmaya Değer Bir Sarmalayıcı

SuperAgent’ın zincirleme işleyişi istek bazındadır; bu da, en önemli tek çağrıda proxy yapılandırmasını unutmanın kolay olduğu anlamına gelir. İstek oluşturma işlemini sarmalamak bu sorunu çözer ve geri kalan varsayılan ayarları yerleştirebileceğiniz bir alan sağlar.

import request from "superagent";
import { ProxyAgent } from "proxy-agent";

const agent = process.env.PROXY_URL ? new ProxyAgent(process.env.PROXY_URL) : undefined;

const UA = "AcmeBot/1.0 (+https://acme.example.com/bot)";

function req(method, url) {
  const r = request[method](url)
    .set("User-Agent", UA)
    .timeout({ response: 15000, deadline: 60000 })
    .retry(2, (err, res) => {
      if (res?.status === 407 || res?.status === 401) return false;
      if (res?.status === 429) return false;   // honour the rate limit instead
      return true;
    });
  return agent ? r.agent(agent) : r;
}

export const get = url => req("get", url);
export const post = url => req("post", url);

export async function verifyExit() {
  const res = await get("https://api.ipify.org?format=json");
  console.log(`Exit address: ${res.body.ip}`);
  return res.body.ip;
}

Buradaki beş seçenek kasıtlı olarak seçilmiştir.

Proxy isteğe bağlıdır ve ortamdan gelir. PROXY_URL yoksa, ajan undefined olur ve istekler doğrudan gönderilir; bu da uygulama kodunuzda dallanma olmadan yerel geliştirme ve üretim ortamlarının öngörülebilir şekilde çalışmasını sağlar. Kaynak kodda hiçbir kimlik bilgisi görünmez.

Yapıcı argümanı olmayanProxyAgent, ortam odaklı yapılandırmayı tercih ederseniz http_proxy ve benzerlerini okur; URL'yi açıkça aktarmak, doğru kaynağın ne olduğunu açıkça ortaya koyar ve bu genellikle daha değerlidir.

Kullanıcı ajanı dürüsttür ve bir iletişim URL'si içerir. Bunun hiçbir maliyeti yoktur ve bir site operatörü sizi fark ettiğinde ne olacağını değiştirir.

Yeniden denemeler, yeniden denemenin anlamsız veya kaba olacağı durumları hariç tutar. Geçersiz kimlik bilgileriyle alınan bir 407 hatası her seferinde 407 olacaktır; bir 429 hatası ise yavaşlama talimatıdır ve bu hataya karşı yeniden deneme yapmak, geçici bir sınırlamayı daha uzun süreli bir sınırlamaya dönüştürür.

verifyExit() dosyası dışa aktarılır ve başlangıçta çağrılır. Sessizce atlanan bir proxy’yi günlüklerdeki bir satıra dönüştüren altı satır — bu, her istemcide proxy çalışmasının tek tekrarlanan temasıdır ve hiçbir kütüphanenin sizin için yapmayacağı tek şeydir.

.connect() Bir Proxy Değildir

Görünüşte bir proxy gibi göründüğü halde aslında olmadığı için dikkat çekmeye değer.

SuperAgent, belgelere göre “DNS çözümlemesini göz ardı etmeyi ve tüm istekleri belirli bir IP adresine yönlendirmeyi” mümkün kılan bir .connect() yöntemi sunar. Bu yöntem, * yedek adresini de içeren bir eşlemeyi destekler:

const res = await request.get("http://redir.example.com:555")
  .connect({
    "redir.example.com": "127.0.0.1",
    "www.example.com": false,
    "mapped.example.com": { host: "127.0.0.1", port: 8080 },
    "*": "proxy.example.com",
  });

Belgelerde, "isteklerin Host başlığını orijinal değeriyle koruyacağı" ve .connect(undefined) komutunun bu özelliği devre dışı bırakacağı belirtilmektedir.

Bu, proxy kullanımı değil, ana bilgisayar yönlendirmesidir. İsteği değiştirmeden bağlantının kurulacağı adresi değiştirir — CONNECT tüneli, proxy protokolü ve proxy kimlik doğrulaması yoktur. Bu özellik test amaçlıdır ve belgelerde haklı bir nedenle "localhost üzerinde test etme" başlığı altında yer almaktadır.

Resmi örnekteki "*": "proxy.example.com" satırı, kafa karışıklığının kaynağıdır. İstekleri yerel bir test sunucusuna yönlendirmek için .connect() kullanın; gerçek bir proxy için bir ajan kullanın.

Sık Sorulan Sorular

SuperAgent ile proxy nasıl kullanılır?

.agent()’a bir proxy ajanı aktarın: proxy URL’nizle bir HttpsProxyAgent veya SocksProxyAgent oluşturun ve bunu isteğe aktarın. Alternatif olarak, .proxy(uri) yöntemini ekleyen superagent-proxy uzantısını kullanabilirsiniz — ancak bu paket 2021’den beri yayınlanmamıştır.

Argümanlı ve argümansız .agent() arasında ne fark vardır?

Argüman olmadan, kendi jar dosyası ve varsayılan seçenekleriyle SuperAgent'ın çerezleri koruyan bir kopyasını oluşturur. Argümanla birlikte ise, o istek için Node'un http.Agent değerini ayarlar; proxy desteği bu şekilde uygulanır. Ortak isim, gerçekten kafa karışıklığına neden olmaktadır.

superagent-proxy hâlâ güncelleniyor mu?

Kullanımdan kaldırılmamıştır, ancak 3.0.0 sürümü Eylül 2021'e aittir; buna karşın temel proxy-agent bağımlılığı yayınlanmaya devam etmiştir — en son Haziran 2026'da. Yeni kodlar için, bir proxy ajanı kullanmak, tek bir satırlık ek maliyet karşılığında eski bir sarmalayıcıyı kullanmaktan kaçınmanızı sağlar.

SuperAgent proxy'm neden çalışmıyor?

Çoğu zaman bunun nedeni, .agent() işlevinin argüman olmadan çağrılmasıdır; bu da proxy ayarlamak yerine bir çerez deposu oluşturur. Ayrıca, SuperAgent zincirleme işlemi her çağrı için ayrı olduğundan, ajanın doğru isteğe uygulandığını da kontrol edin. Adresinizi bildiren bir hizmet talep ederek doğrulayın — atlanan bir proxy hata vermez.

SuperAgent, HTTP_PROXY ortam değişkenlerini dikkate alır mı?

Kendi başına almaz. proxy-agent paketi, http_proxy, https_proxy ve no_proxy değerlerini okur; bu nedenle, argüman içermeyen bir ProxyAgent() oluşturup bunu .agent() adresine aktararak ortam değişkenlerine dayalı bir davranış elde edebilirsiniz.

Proxy üzerinden yapılan istekler için zaman aşımlarını nasıl ayarlayabilirim?

Her iki ayarı da kullanın: .timeout({ response: 15000, deadline: 60000 }). Yanıt zaman aşımı, ilk baytı bekleme süresini sınırlar; son tarih ise tüm isteği sınırlar. Ev tipi çıkış, DNS, bağlantı ve TLS aşamalarına gerçek gecikme eklediğinden, boyutları proxy üzerinden alınan ölçümlere göre belirleyin.

Proxy hatasını hedef hatasından nasıl ayırt edebilirim?

Durum koduna göre. SuperAgent, 4xx ve 5xx kodlarını hata olarak değerlendirir; bu nedenle err.status adresini yakalayıp okuyun — 407 kodu, proxy'nin sizi reddettiği ve hedefe hiç ulaşılamadığı anlamına gelirken, 401 kodu proxy'nin çalıştığını ve hedefin kimlik bilgilerini istediği anlamına gelir. err.status'in hiç olmaması, HTTP yanıtının gelmediği anlamına gelir.

.connect() işlevini proxy olarak kullanabilir miyim?

Hayır. Bu işlev, istekleri belirli bir IP adresine yönlendirirken orijinal Host başlığını korur; bu, proxy işlevi yerine test amaçlı ana bilgisayar eşlemesidir. Tünel, proxy protokolü ve kimlik doğrulama yoktur. Gerçek bir proxy için bir ajan kullanın.

Sonuç

SuperAgent’ın kendine ait bir proxy seçeneği bulunmadığından, seçim bir ajan ya da bir uzantı arasında yapılır — ve ajan varsayılan olarak daha iyi bir seçenektir, çünkü her iki durumda da asıl işi yapanlar, bakımları yapılan paketlerdir.

Asıl tuzak, kullanılan terminolojidir. Argüman içermeyen .agent() komutu size bir çerez kavanozu verir; .agent(something) ise bir HTTP ajanı ayarlar. Kullanıcılar ilk seçeneği yapılandırır, isteklerin başarılı olduğunu görür ve proxy'nin çalıştığı sonucuna varır. Kimse onları düzeltmez, çünkü atlanan bir proxy tanım gereği sessizce başarısız olur.

Bu da doğrulamayı edinilmesi gereken bir alışkanlık haline getirir. Aracı ile ve aracı olmadan adresinizi bildiren bir hizmetten istekte bulunun ve cevabın değiştiğini doğrulayın. Coğrafi hedeflemeli çalışmalar için bir adım daha ileri gidin ve bölgelere göre farklılaşan içeriğin gerçekten farklı olduğunu doğrulayın — adres kısmı kolay olan ve en az bilgi veren kısımdır.

Ardından her iki zaman aşımını da ayarlayın, err.status adresine yönlendirin, böylece 407 ve 401 hataları farklı mesajlara yol açsın, ve .retry() adresini idempotent olmayan her şeyden uzak tutun. Proxy üzerinden, başarılı bir isteğin yanıtını kaybedebileceği ekstra bir geçiş noktası vardır ve bu durumda yeniden deneme, kurtarma değil, yineleme anlamına gelir.