---
title: "JavaScript'te cURL: fetch, Axios ve Proxy"
description: "cURL komutlarının JavaScript karşılığı fetch ve Axios'tur. Başlık, gövde, kimlik doğrulama ve Node.js'te proxy ayarını denenmiş kod örnekleriyle anlatıyoruz."
url: https://proxynet.io/tr/blog/curl-in-javascript
date: 2026-09-13
author: "Acar Diveroli"
category: "Nasıl Yapılır"
lang: tr
---

# JavaScript'te cURL: fetch, Axios ve Proxy

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.

> **Not: Kısa cevap**
>
> `curl URL` komutunun karşılığı `fetch(url)` ya da `axios.get(url)`; `-H` başlıklar `headers` nesnesine, `-d` gövdesi `body`/ikinci parametreye, `-x proxy` ise Node.js'te undici `ProxyAgent` ya da Axios için `https-proxy-agent` ajanına dönüşür. Tarayıcıda çalışan JavaScript'te proxy kod ile tanımlanamaz.

## 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](https://undici.nodejs.org/) 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:

```bash
curl -X POST https://httpbin.org/post \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer TOKEN" \
  -d '{"q": 1}'
```

### fetch ile

```javascript
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

```bash
npm install axios
```

```javascript
import 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:

```javascript
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.

```javascript
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:

```bash
npm install undici
```

```javascript
import { 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](/tr/blog/nodejs-proxy) yazısıdır.

> **İpucu**
>
> Proxy adresi `http://` ile başlasa bile HTTPS sitelere güvenle gidebilirsiniz. Proxy ile HTTP üzerinden bir tünel kurulur ve sitenin HTTPS trafiği bu tünelin içinde şifreli olarak taşınır. Farkların ayrıntısı [SOCKS ve HTTP Proxy Farkı](/tr/blog/socks-vs-http-proxy) yazımızda.

## 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:

```javascript
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](https://proxynet.io/tr/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?](/tr/blog/web-scraping-javascript-vs-python) yazımızda karşılaştırdık; Puppeteer ile proxy kullanımını [Puppeteer ve CAPTCHA](/tr/blog/puppeteer-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. Aynı komutu Python'a taşıyorsanız cURL seçeneklerinin `json=`, `data=` ve `params=` karşılıklarını [Python Requests ile POST ve JSON: cURL Karşılıkları](/tr/blog/python-requests-post-json) yazımızda tablo hâlinde verdik.

### 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?](/tr/blog/curl-proxy) 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](/tr/blog/switchy-omega) 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](https://proxynet.io/tr/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ı](/tr/blog/nodejs-proxy) 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](https://proxynet.io/tr/https-proxy) sayfamızda bulabilirsiniz.
