API belgeleri ve tarayıcının geliştirici araçları çoğu zaman örnek isteği bir cURL komutu olarak verir. Terminalde hızlı bir deneme için idealdir; ama aynı isteği bir Node.js uygulamasına ya da kazıma betiğine taşımanız gerektiğinde komutu JavaScript'e çevirmeniz gerekir. Bu yazıda en sık kullanılan cURL seçeneklerinin JavaScript karşılıklarını, çeviri örneklerini, -x seçeneğinin Node.js karşılığını, hata yönetimini ve sık yapılan hataları anlatıyoruz.
Örneklerin tamamı Node.js 24 üzerinde, undici 8 ve Axios 1.20 ile denenmiştir.
JavaScript'te cURL'ün karşılığı nedir?
İki ana seçenek var:
- fetch: Tarayıcılarda ve Node.js 18'den bu yana yerleşik olarak gelir. Ek paket gerektirmez. Node.js'in fetch uygulaması arka planda undici kütüphanesini kullanır.
- Axios: Uzun süredir kullanılan, JSON dönüşümünü otomatik yapan, istek ve yanıt araya girme (interceptor) desteği sunan popüler bir kütüphane.
Terminalden çıkmadan bir cURL komutunu yeniden kullanmak da mümkündür (child_process ile), ancak bu yöntem hata yönetimini ve taşınabilirliği zorlaştırır; cURL'ün makinede kurulu olmasına bağımlı kalırsınız. Yerel bir istemciyle yazmak neredeyse her zaman daha iyidir.
cURL seçeneklerinin JavaScript karşılıkları
| cURL | fetch | Axios |
|---|---|---|
curl URL | fetch(url) | axios.get(url) |
-X POST | method: "POST" | axios.post(url, veri) |
-H "Ad: Değer" | headers: { Ad: "Değer" } | headers: { Ad: "Değer" } |
-d '{"a":1}' | body: JSON.stringify({ a: 1 }) | ikinci parametre olarak nesne |
-d "a=1&b=2" | body: new URLSearchParams({ a: 1, b: 2 }) | new URLSearchParams(...) ikinci parametre |
-F "dosya=@a.png" | body: FormData | FormData ikinci parametre |
-u kullanici:parola | Authorization: "Basic ..." başlığı | auth: { username, password } |
-b "ad=deger" (çerez) | headers: { Cookie: "ad=deger" } | headers: { Cookie: "ad=deger" } |
-A "UA" | headers: { "User-Agent": "UA" } | headers: { "User-Agent": "UA" } |
-L (yönlendirmeyi izle) | Varsayılan olarak izler | Varsayılan olarak izler |
-x proxy | dispatcher: new ProxyAgent(...) | httpsAgent veya proxy |
-m 20 (zaman aşımı) | signal: AbortSignal.timeout(20000) | timeout: 20000 |
-i (yanıt başlıkları) | response.headers | response.headers |
-o dosya | fs.writeFile ile gövdeyi yazın | responseType: "stream" |
Örnek: bir POST isteğini çevirmek
Şu cURL komutunu ele alalım:
curl -X POST https://httpbin.org/post \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TOKEN" \
-d '{"q": 1}'fetch ile
const response = await fetch("https://httpbin.org/post", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer TOKEN",
},
body: JSON.stringify({ q: 1 }),
signal: AbortSignal.timeout(20000),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
console.log(data.json);fetch'in bir inceliği var: Sunucu 404 veya 500 döndürdüğünde hata fırlatmaz. Yanıtın başarılı olup olmadığını response.ok ile kendiniz kontrol etmelisiniz. Ağ hatası (DNS, bağlantı reddi, zaman aşımı) ise istisna olarak gelir.
Axios ile
npm install axiosimport axios from "axios";
const { data } = await axios.post(
"https://httpbin.org/post",
{ q: 1 },
{ headers: { Authorization: "Bearer TOKEN" }, timeout: 20000 },
);
console.log(data.json);Axios nesneyi JSON'a kendisi dönüştürür, Content-Type başlığını ekler ve 2xx dışındaki yanıtlarda hata fırlatır.
Örnek: form gönderimi ve dosya yükleme
cURL'de -d "a=1&b=2" biçimindeki bir form gönderimi JavaScript'te URLSearchParams ile karşılanır:
const response = await fetch("https://httpbin.org/post", {
method: "POST",
body: new URLSearchParams({ a: "1", b: "2" }),
});
console.log((await response.json()).form);URLSearchParams gövdesi verildiğinde fetch Content-Type başlığını kendisi application/x-www-form-urlencoded yapar. Dosya yüklemede (-F) ise FormData kullanılır ve sınır (boundary) değeri yine otomatik eklenir. Bir ayrıntı: fetch fonksiyonunu undici paketinden alıyorsanız FormData sınıfını da aynı paketten alın; yerleşik FormData ile undici'nin fetch'i eşleşmez ve gövde düz metin olarak gider.
import { openAsBlob } from "node:fs";
const form = new FormData();
form.append("dosya", await openAsBlob("./a.png"), "a.png");
const response = await fetch("https://httpbin.org/post", { method: "POST", body: form });
console.log(Object.keys((await response.json()).files));cURL'deki -x seçeneğinin Node.js karşılığı
cURL'de proxy tek bir -x seçeneğidir. Node.js'te ise hangi istemciyi kullandığınıza göre yöntem değişir: yerleşik fetch proxy'yi dispatcher ile, Axios ve node-fetch ise agent ile alır. En kısa karşılık undici paketiyle yazılır:
npm install undiciimport { fetch, ProxyAgent } from "undici";
const dispatcher = new ProxyAgent("http://kullanici:parola@pr.proxynet.io:8000");
const response = await fetch("https://httpbin.org/ip", { dispatcher });
console.log(await response.text());fetch fonksiyonunu da undici paketinden içe aktardığımıza dikkat edin. npm'den kurulan undici'nin ProxyAgent'ını Node.js'in yerleşik fetch'ine vermek, iki undici sürümü uyuşmadığında fetch failed hatasıyla sonuçlanır.
Axios ve https-proxy-agent, node-fetch, NODE_USE_ENV_PROXY ortam değişkeni, SOCKS5, kimlik doğrulama hatalarının kütüphaneden kütüphaneye nasıl göründüğü ve rotasyonlu bir örnek için ayrıntılı rehberimiz Node.js'te Proxy Kullanımı: Axios ve node-fetch yazısıdır.
Yeniden deneme ve eşzamanlılık
Gerçek bir kazıma betiğinde istekler bazen başarısız olur; proxy hedefe ulaşamayabilir ya da site 429 döndürebilir. Aşağıdaki yardımcı fonksiyon, başarısız isteği üstel bekleme ile yeniden dener ve aynı anda açık istek sayısını sınırlar:
import { fetch, ProxyAgent } from "undici";
const dispatcher = new ProxyAgent("http://kullanici:parola@pr.proxynet.io:8000");
async function getir(url, deneme = 3) {
for (let i = 0; i < deneme; i++) {
try {
const r = await fetch(url, { dispatcher, signal: AbortSignal.timeout(20000) });
if (r.status === 429 || r.status >= 500) throw new Error(`HTTP ${r.status}`);
return await r.text();
} catch (hata) {
if (i === deneme - 1) throw hata;
await new Promise((coz) => setTimeout(coz, 1000 * 2 ** i));
}
}
}
async function topluGetir(urls, esZamanli = 5) {
const sonuclar = [];
for (let i = 0; i < urls.length; i += esZamanli) {
const grup = urls.slice(i, i + esZamanli);
sonuclar.push(...(await Promise.allSettled(grup.map(getir))));
}
return sonuclar;
}
const urls = Array.from({ length: 20 }, (_, i) => `https://httpbin.org/get?i=${i}`);
const sonuclar = await topluGetir(urls);
console.log(sonuclar.filter((s) => s.status === "fulfilled").length, "başarılı");Promise.allSettled bir isteğin hatası yüzünden tüm grubun düşmesini önler; her sonucu tek tek inceleyebilirsiniz. Bekleme süresi her denemede ikiye katlanır; sabit aralıkla ısrar etmek hız sınırı uygulayan bir siteyi daha da sertleştirir.
Sık yapılan hatalar
Parolada özel karakter
Proxy parolanızda @, : veya / gibi karakterler varsa adresin içinde encodeURIComponent ile kodlayın. Aksi halde adres yanlış ayrıştırılır ve "407 Proxy Authentication Required" hatası alırsınız.
Zaman aşımı olmayan istekler
Varsayılan ayarlarda bir istek uzun süre yanıt bekleyebilir ve betiğiniz takılı kalır. fetch'te AbortSignal.timeout, Axios'ta timeout ile her isteğe süre sınırı koyun.
Aynı anda çok fazla istek
Promise.all ile yüzlerce isteği birden başlatmak hem kendi bağlantı sınırlarınızı zorlar hem de hedef sitede hız sınırına takılmanıza neden olur. Eşzamanlılığı yukarıdaki gibi küçük gruplar halinde sınırlayın. Çok sayıda istek gönderdiğiniz işlerde Rotating Proxy trafiği farklı IP'lere dağıtarak engellenme riskini azaltır.
Yerleşik fetch'e agent vermek
Node.js'in eski http.request API'sinde proxy agent seçeneğiyle verilir. Yerleşik fetch bu seçeneği tanımaz ve sessizce yok sayar; istek proxy'siz gider. fetch için doğru anahtar dispatcher'dır.
Tarayıcı başlıklarını olduğu gibi kopyalamak
Geliştirici araçlarından kopyalanan istekler sec-ch-ua, sec-fetch-* gibi tarayıcıya özgü başlıklar taşır. Node.js'te bunları göndermek gerekmez ve bazıları hedef sitede tutarsızlık olarak değerlendirilebilir; yalnızca gerçekten gereken başlıkları bırakın.
HTTP isteğinin yetmediği sayfalar
fetch ve Axios yalnızca sunucunun döndürdüğü HTML'i alır. İçerik tarayıcıda JavaScript ile sonradan yükleniyorsa sayfada aradığınızı bulamazsınız. Bu durumda ya arka plandaki API isteğini bulmanız ya da bir tarayıcı otomasyonu kullanmanız gerekir. Seçenekleri Web Kazıma: JavaScript mi Python mu? yazımızda karşılaştırdık; Puppeteer ile proxy kullanımını Puppeteer ve CAPTCHA yazımızda gösterdik.
fetch mi Axios mu?
- fetch seçin: Ek bağımlılık istemiyorsanız, kod hem tarayıcıda hem Node.js'te çalışacaksa veya undici'nin bağlantı yönetimi özelliklerinden yararlanmak istiyorsanız.
- Axios seçin: Otomatik JSON dönüşümü, interceptor'lar ve 2xx dışı yanıtlarda hata fırlatma gibi kolaylıklara ihtiyacınız varsa veya projede zaten kullanılıyorsa.
İkisi arasındaki fark, işlevden çok alışkanlıktır. Yeni bir projede fetch ile başlamak bağımlılık sayısını düşük tutar; büyük bir Axios projesinde fetch'e geçmek için bir neden yoktur.
Sık sorulan sorular
cURL komutunu otomatik olarak JavaScript'e çevirebilir miyim?
Tarayıcının geliştirici araçlarında Ağ sekmesinden bir isteği sağ tıklayıp "Copy as fetch" seçeneğiyle doğrudan fetch kodu olarak kopyalayabilirsiniz. Ortaya çıkan kodu yine de gözden geçirin; tarayıcıya özgü başlıklar Node.js'te gereksiz olabilir.
Node.js'te SOCKS5 proxy kullanabilir miyim?
Yerleşik fetch ve undici ProxyAgent HTTP proxy içindir. SOCKS5 için socks-proxy-agent gibi ek bir paketle ajan tanımlamanız gerekir. cURL tarafında ise socks5h:// şeması doğrudan desteklenir; ayrıntılar cURL ile Proxy Nasıl Kullanılır? yazımızda.
Tarayıcıda çalışan JavaScript'te proxy tanımlanabilir mi?
Hayır. Tarayıcıdaki fetch, proxy ayarını kod üzerinden değiştirmenize izin vermez; proxy tarayıcının veya işletim sisteminin ayarlarında tanımlanır. Kod içinden proxy yönetimi Node.js gibi sunucu ortamlarına özgüdür. Tarayıcı düzeyinde proxy için SwitchyOmega gibi eklentiler kullanılır.
Çerezleri istekler arasında nasıl korurum?
Yerleşik fetch çerez saklamaz. Set-Cookie başlığını yanıttan okuyup sonraki isteğe Cookie başlığı olarak eklemeniz gerekir; ya da Axios ile tough-cookie tabanlı bir çerez kavanozu kullanabilirsiniz. Giriş yapılan akışlarda IP'nin de sabit kalması gerektiğini unutmayın; Sticky Proxy bu iş için tasarlanmıştır.
Her istekte farklı proxy kullanabilir miyim?
Evet. undici ile her çağrıya farklı bir ProxyAgent verebilirsiniz. Ancak listeyi kendiniz yönetmek yerine rotating proxy kullanmak daha basittir: tek adres, her bağlantıda farklı çıkış IP'si.
TypeScript'te aynı kod çalışır mı?
Evet. undici ve Axios tür tanımlarıyla gelir; dispatcher seçeneği için undici'nin kendi fetch türünü kullanmak gerekir, çünkü yerleşik fetch'in tür tanımı bu seçeneği bilmez.
Özetle
cURL komutları JavaScript'te fetch veya Axios ile birebir karşılanabilir. cURL'deki -x seçeneğinin en kısa Node.js karşılığı undici ProxyAgent'tır; Axios, node-fetch, ortam değişkenleri ve SOCKS5 için Node.js'te Proxy Kullanımı rehberimize bakabilirsiniz. Zaman aşımı, hata kontrolü, üstel bekleme ile yeniden deneme ve eşzamanlılık sınırını baştan eklemek betiklerinizi çok daha güvenilir kılar. Web trafiği için uygun paketleri HTTPS Proxy sayfamızda bulabilirsiniz.




