> ## Content Index
> Fetch the complete content index at: https://www.tool-cloud.com/blog/tr/llms.txt
> Use this file to discover other available public pages before exploring further.

# JavaScript'te Metni Base64'e Dönüştürme (ve Çözümleme)
- URL: https://www.tool-cloud.com/blog/tr/javascript-te-metni-base64-e-donusturme-ve-cozumleme/
- Published: 2026-10-14T18:18:34.000Z
- Updated: 2026-10-14T18:29:01.000Z
- Description: Çalışan tek satırlık kod, hata veren ve neden verdiği; UTF-8 güvenli dönüşüm, 2025 yerel yöntemleri ve Node.js farkları.
- Author: Tool Cloud Team
- Tags: Geliştiriciler, Rehberler

JavaScript'te bir dizeyi base64'e kodlamak için `btoa('Hello, world!')` çağrısı yapın; bu `'SGVsbG8sIHdvcmxkIQ=='` döndürür. Ancak bu tek satırlık kod yalnızca ASCII ve Latin-1 metinler için çalışır: Bir emoji, vurgu işareti veya Çince karakter geçirdiğiniz anda `InvalidCharacterError` hatası verir. Bu rehber, bunun neden olduğunu ve sorunu çözen UTF-8 güvenli dönüşümü, 2025'teki yeni yerel yöntemler de dahil olmak üzere gösterir.

## Tek satırda Base64: btoa() ve atob()

En hızlı çözüm: `btoa('Hello, world!')` ile kodlayın, `atob('SGVsbG8sIHdvcmxkIQ==')` ile çözün. İkisi de doğrulandı: `btoa('a')` `'YQ=='` döndürür ve `atob('SA==')` `'S'` döndürür.

[btoa()](https://developer.mozilla.org/en-US/docs/Web/API/Window/btoa) aslında ne yapar? Dizenizi "ikili dize" (binary string) olarak ele alır; yani her karakterin ikili verinin tam olarak bir baytını temsil ettiği bir dize oluşturur ve bu baytları Base64'e kodlar. MDN'deki kullanım durumu, metin tabanlı kanallar üzerinden taşımak istediğiniz ASCII kontrol karakterleri (0–31) gibi aktarım sorunlarına neden olan verilerdir.

Metniniz ASCII ise bu tek satırlık kod yeterlidir: Her karakterin kod noktası 256'nın altında olmalı ve MDN'e göre bayt-kod noktası eşleşmesi güvenilir şekilde yalnızca 0x7F'e kadar geçerlidir. 0x80–0xFF aralığı teknik olarak çalışsa da, bu durum ortamlar arasında taşınabilir olmayan Latin-1 kodlama davranışına dayanır. İyi bir kural şudur: ASCII dışı her şey için aşağıdaki UTF-8 yolunu izleyin.

## Neden btoa() emoji, vurgular ve CJK metinlerde InvalidCharacterError verir?

Base64 bir ikili kodlamadır, metin kodlaması değildir. [MDN sözlüğü](https://developer.mozilla.org/en-US/docs/Glossary/Base64), rastgele metin veya HTML'i `btoa()`'e aktarma alışkanlığının yaygın bir yanlış anlama olduğunu belirtir: `btoa`/`atob` türü belirlenmiş dizilerden (typed arrays) önce geldiği için baytları temsil etmek üzere dizeleri kullanır. Sorun, dizenizin karakter başına bir bayt karşılığı gelmediği zaman başlar.

JavaScript dizeleri UTF-16'dır; bu nedenle bir kod birimi her zaman iki bayttır ve BMP dışındaki karakterler (emoji gibi) bir sürrogat çifti olarak dört bayt kaplar; UTF-8 ise kod noktası başına bir ila dört bayt kullanır. `btoa()` ve `atob()` yalnızca tek baytlı (Latin-1 aralığındaki) karakterlerle çalışır. Daha geniş bir şeyi kodlamaya çalıştığınızda şu hatayı alırsınız:

```
DOMException: Failed to execute 'btoa' on 'Window':
The string to be encoded contains characters outside of the Latin1 range

```

Kırılma durumu kolayca yeniden üretilebilir: `btoa('✓')` hata verir, `btoa('a Ā 𐀀 文 🦄')` de öyle. Emoji, Latin-1 dışı vurgulu harfler ve CJK karakterlerinin hepsi 0xFF'nin üzerindedir, bu nedenle hiçbirisi karakter başına bir bayt varsayımına uymaz. `'✓'` U+2713'tür, 0xFF'nin çok üzerindedir, bu nedenle `btoa()` verinizi sessizce bozmaktansa reddeder. Bu reddetme, API'nin en iyi özelliği olabilir: haftalar sonra keşfedeceğiniz mojibake (bozuk metin) üretmek yerine gürültülü bir şekilde başarısız olur.

Bunu düzeltmeden önce bilinmesi gereken bir şey daha: Base64, ham baytlara kıyasla veriyi yaklaşık %33 oranında büyütür. Kısa dizeler, belirteçler ve veri URI'ları için bu sorun değildir, ancak büyük yükleri Base64'e kodlamamak için gerçek bir neden vardır: İhtiyacınız olan sınırda kodlayın, her yerde değil.

![Soldan akan ve iki yola ayrılan yumuşak 3D mavi kurdele: bir dal düzenli kümelenmiş gruplar oluşturur…](https://www.tool-cloud.com/blog/tr/content/images/2026/10/javascript-base64-encode-utf8-split.webp)

Bir veri akışı, iki bayt ayak izi: Çok baytlı kümeler versus tek baytlar.

### Yalnız sürrogat uç durumu (ve String.isWellFormed())

Çoğu makale bunu atlar ama gerçekten can acıtır: Yalnız bir sürrogat içeren (genellikle dilimleme hatasından kaynaklanan bir emoji çiftinin yarısı) bir UTF-16 dizesi "bozuktur" (malformed). [web.dev rehberi](https://web.dev/articles/base64-encoding)'ne göre, `TextDecoder` öntanımlı olarak U+FFFD'yi sessizce yerleştirir. Kodlamadan önce `String.prototype.isWellFormed()` ile iyi biçimli olup olmadığını kontrol edin veya yalnız sürrogatlar için `encodeURIComponent()`'ün fırlattığı `URIError` hatasını yakalayın; ardından ne yapacağınıza açıkça karar verin: Veriyi reddedin, değiştirmeyi bilerek etkinleştirin ya da sonraki analiz için hata fırlatın.

## Doğru yol: TextEncoder → UTF-8 baytları → Base64

Doğru düzeltme, dizenizi önce `TextEncoder` ile UTF-8 baytlarına dönüştürüp dizeyi değil baytları Base64'e kodlamaktır. `new TextEncoder().encode(str)`, herhangi bir JavaScript dizesini UTF-8 baytlarından oluşan bir `Uint8Array`'e dönüştürür (TextEncoder yalnızca UTF-8'i destekler). Geri dönüşte `new TextDecoder()` öntanımlı olarak UTF-8 kullanır ve dönüşümü tam olarak tersine çevirir. Burada `atob()`'ün size ne verdiğine dikkat edin: Bir ikili dize, karakter başına bir bayt; UTF-8 metin değil. Bu nedenle decode tarafında baytları tekrar okunabilir metne çevirmek için `TextDecoder` gerekir.

### bytesToBase64() ve base64ToBytes() yardımcı fonksiyonları (kopyala-yapıştır kod)

İşte [MDN'in referans dönüşümü](https://developer.mozilla.org/en-US/docs/Web/API/Window/btoa); bu kod, `TextEncoder`'i destekleyen tüm tarayıcılarda çalışır (IE hariç):

```js
function bytesToBase64(bytes) {
  const binString = Array.from(bytes, (b) => String.fromCodePoint(b)).join('');
  return btoa(binString);
}

function base64ToBytes(base64) {
  const binString = atob(base64);
  return Uint8Array.from(binString, (m) => m.codePointAt(0));
}

```

### Tam bir dönüşümle doğrulayın

Bir dizeyi kodlamak bir satıra iner:

```js
const encoded = bytesToBase64(new TextEncoder().encode('a Ā 𐀀 文 🦄'));
// 'YSDEgCDwkICAIOaWhyDwn6aE'

```

Çözümleme bunu tersine çevirir:

```js
const decoded = new TextDecoder().decode(base64ToBytes(encoded));
// 'a Ā 𐀀 文 🦄'

```

web.dev'in doğrulanmış dönüşümü aynı deseni onaylar: `'hello⛳❤️🧀'` `'aGVsbG/im7PinaTvuI/wn6eA'`'ye kodlar ve emoji dahil olmak üzere tam olarak geri çözer.

### unescape(encodeURIComponent()) hilesini atlayın

`btoa(unescape(encodeURIComponent(str)))` kodunu her yerde kopyalanmış halde bulacaksınız. Çalışır, ancak `unescape()` Ek B mirasıdır ve ECMAScript 3'ten beri kullanımdan kaldırılmıştır. Yeni kod bunun yerine `TextEncoder` kullanmalıdır: Açıktır, standarttır ve kullanımdan kaldırılmış bir global'e dayanmaz.

## 2025 yolu: Uint8Array.toBase64() ve Uint8Array.fromBase64()

Eylül 2025'ten itibaren JavaScript'te `Uint8Array` üzerinde yerel Base64 yöntemleri mevcuttur; bu nedenle yukarıdaki bayt-dizisi yardımcı fonksiyonları artık tek seçenek değildir. TC39'un [Base64 önerisi](https://github.com/tc39/proposal-arraybuffer-base64/blob/main/README.md) 4\. aşamaya ulaştı ve dilin bir parçasıdır; TC39'un gerekçesi, base64'ün bir metin kodlaması olmamasıdır, bu nedenle TextEncoder/TextDecoder kavramsal olarak bunun için yanlış araçlardır.

[MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global%5FObjects/Uint8Array/toBase64)'ye göre bu yöntemler, güncel tarayıcılarda "Yeni kullanıma açılan" kategoriye girer. Göndermeden önce hedef çalışma ortamlarınızı kontrol edin; eski tarayıcıları veya eski Node sürümlerini destekliyorsanız `TextEncoder` \+ `btoa` yedekleme mekanizmasını koruyun. MDN, zaten bir `Uint8Array` varsa `btoa()`/`atob()` yerine bu yöntemleri tercih eder çünkü ham bayt dizisi oluşturulmasına gerek kalmaz.

### Kodlama: bytes.toBase64()

```js
const b64 = new TextEncoder().encode('Hello, world!').toBase64();
// 'SGVsbG8sIHdvcmxkIQ=='

```

Tek bir UTF-8 dönüşümü, tek bir yöntem çağrısı ve iş biter.

### Çözümleme: Uint8Array.fromBase64()

```js
const text = new TextDecoder().decode(Uint8Array.fromBase64(b64));
// 'Hello, world!'

```

MDN, çözümlenen verinin ASCII metin olarak amaçlanmadığı sürece `fromBase64()`'in `atob()`'e tercih edilmesi gerektiğini belirtir; çünkü gerçek bir bayt dizisi döndürür. Yalnızca base64 alfabesini (A–Z, a–z, 0–9, artı `+/` veya `-_`), isteğe bağlı `=` dolgu karakterini kabul eder ve ASCII boşluklarını yok sayar; alfabenin dışında kalan karakterlerde `SyntaxError` hatası verir.

### Seçenekler: alphabet, omitPadding, lastChunkHandling

[Spesifikasyonun seçenek paketi](https://tc39.es/proposal-arraybuffer-base64/) size hassas kontrol sağlar:

| Seçenek           | Değerler                                              | Ne işe yarar                                                                                            |
| ----------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| alphabet          | 'base64' (varsayılan), 'base64url'                    | +// vs \-/\_                                                                                            |
| omitPadding       | boolean                                               | Son \= karakterlerini atar: new Uint8Array(\[72\]).toBase64() → 'SA==', omitPadding ile birlikte → 'SA' |
| lastChunkHandling | 'loose' (varsayılan), 'strict', 'stop-before-partial' | Son parça için çözümleyici toleransı                                                                    |

`'loose'` eksik dolgu ve boşluğu tolere eder. `'strict'`, taşan bitlerin sıfırlandığı tam 4 karakterlik parçaları gerektirir; bu da güvenilir olmayan girdileri doğrularken istediğiniz davranıştır. `'stop-before-partial'` akışlı kullanım içindir. Varsayılan gevşek mod, sıkı modun reddettiği sıfırdan farklı taşan bitleri de tolere eder.

## Base64 vs base64url: Hangi alfabe gerekiyor?

Standart base64, `+` ve `/`'i kullanır ve `=` dolgusu ile birlikte, yol segmenti veya sorgu dizesi içermeyen `data:` URL'leri için uygundur. base64url (RFC 4648 §5) ise `-` ve `_`'yı kullanır ve genellikle dolguyu atar; çıktı bir URL içinde iletilecekse base64url zorunludur. Örneğin JWT'ler üç segmentinin tamamında base64url kullanır.

### Ne zaman base64url kullanılmalı

Kodlanmış dize bir URL yolunun veya sorgu parametresinin parçası olduğunda base64url kullanın; `+` ve `/` burada kaçış karakteri gerektirir ve `=` dolgusu sorgu dizelerini karmaşıklaştırır. Veri URI'ları, JSON yüklerine bayt gömme veya URL dışı herhangi bir durum için standart base64 kullanın.

### base64url nasıl üretilir

Ortama bağlı olarak üç yol vardır:

- Modern tarayıcılar: `bytes.toBase64({ alphabet: 'base64url' })`
- Node 16+: `Buffer.from(str).toString('base64url')`
- Son işlem: Standart çıktıyı alın, `+` → `-` ve `/` → `_` değişimlerini yapın, ardından `=` dolgusunu kaldırın.

Bilmeye değer ince bir nokta: RFC 4648, kodlayıcılardan son parçada veri dışı taşan bitleri sıfırlamasını ister; sıkı çözümleyiciler bunlar sıfırlanmadığında hata verebilir. MDN'un sözlüğü, kirli dolgu bitlerine sahip olsa da `'VQ=='` ile aynı bayt olan `'VR=='` örneğini verir. İyi davranan bir kodlayıcıyla base64 üretirseniz bu sorun hiç çıkmaz; kendiniz yazarsanız çıkabilir.

## Dosya veya resmi Base64'e dönüştürme (veri URI'ları)

Dosyalar için tarayıcı yolu, tam bir veri URI'sı üreten `FileReader` ile `readAsDataURL()` kullanmaktır; ardından ön eki çıkararak ham base64'e ulaşırsınız. Zaten bir canvas üzerinde render edilmiş görüntüler için `toDataURL('image/png')` tek bir çağrıyla bu işi halleder.

### FileReader.readAsDataURL() → veri URI'sı → ham base64

```js
function fileToDataURL(file) {
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result);
    reader.readAsDataURL(file);
  });
}

const dataUrl = await fileToDataURL(fileInput.files[0]);
const rawBase64 = dataUrl.replace(/^data:\w+\/\w+;base64,/, '');

```

### Görüntüler için canvas.toDataURL()

Bir görüntüyü canvas üzerine çizdiyseniz (boyutlandırma, kırpma vb.), FileReader'ı tamamen atlayın:

```js
const dataUrl = canvas.toDataURL('image/png');

```

Sadece ham base64 stringine ihtiyacınız varsa aynı ön ek çıkarma işlemi geçerlidir.

### Veri URI'sından baytlara geri dönüş

Ters yön bir fetch ve bir array buffer işlemidir. MDN'un örneğinde, `new Uint8Array([0,1,2])`'den oluşturulan bir veri URI'sı `'data:application/octet-stream;base64,AAEC'` şeklindedir ve baytları şu şekilde geri kazanırsınız:

```js
const res = await fetch(dataUrl);
const bytes = new Uint8Array(await res.arrayBuffer());
// [0, 1, 2]

```

Bu makalenin var olma amacını özetleyen hatırlatma: Veri URI'ları oluşturmak için rastgele metin veya HTML üzerinde `btoa()` çağırmayın. Bu, bayttan bayta çalışan bir kodlayıcıdır ve Latin-1 dışı girdilerde hata verecektir.

## Node.js: Buffer.from(str, 'base64') — ve bu yöntemin tek tehlikeli farkı

Node.js, TextEncoder işlemlerini tamamen atlayan kendi yöntemlerine sahiptir: `Buffer.from('Hello, world! 🌍').toString('base64')` başından beri baytlar üzerinde çalıştığı için Unicode'u otomatik olarak yönetir. Çözümleme için `Buffer.from(encoded, 'base64').toString('utf8')` kullanın.

Başka faydalı biçimler: `Buffer.from(str).toString('base64url')` (Node 16 ve üzeri) ve tüm dosyalar için `fs.readFileSync('image.png').toString('base64')`.

```js
const encoded = Buffer.from('Hello, world! 🌍').toString('base64');
const decoded = Buffer.from(encoded, 'base64').toString('utf8');

```

### Node base64'ünüzü doğrulamaz (sessiz hatalar)

İnsanları şaşırtan kısım şu: Node.js'in base64 çözücüsü girdiyi doğrulamaz. `Buffer.from('!!!!', 'base64').toString()` hata vermeden `''` döndürür ve `Buffer.from('aGVsbG8!!!', 'base64')` geçersiz (çöp) karakterleri sessizce atarak `'hello'` sonucunu verir. Buna karşılık, `atob('aGVsbG8!!!')` bir `InvalidCharacterError` hatası fırlatır. Base64 verisi kullanıcılar, bir API veya üçüncü taraflardan geliyorsa, Node.js'te çözümden önce doğrulama yapın veya çalışma zamanları destekliyorsa `Uint8Array.fromBase64()` ile `lastChunkHandling: 'strict'` kullanın.

### btoa/atob kullanımdan kaldırıldı mı? Tarayıcılar vs Node

Bu durum gerçekten çelişkili görünüyor, bu yüzden dürüst bir çözüm sunalım. Tarayıcılar için [MDN, btoa() ve atob()'yi işaretler](https://developer.mozilla.org/en-US/docs/Web/API/Window/btoa) Temel özellik olarak Temmuz 2015'ten itibaren geniş ölçüde mevcut; artık kullanımdan kaldırılmadı. Node.js ortamında ise [tip tanımları](https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/58795) bu fonksiyonları `@deprecated` "yeni kodlarda asla kullanılmamalı" yorumuyla birlikte işaretler ve `Buffer.from(str, 'base64')` kullanımını önerir.

İyi bir kural: Bu kaldırılmış bir API değil, miras kalan (legacy) bir API'dir. Tarayıcı kodunda sorun yok; ancak Node'a özel kodlarda `Buffer` tercih edilmelidir. Topluluk görüşüne dayanarak (bir standart garantisi olmasa da), tarayıcılar, Deno ve Node ortamlarında bağımlılık olmadan aynı kodun çalışmasını istiyorsanız, pratik olarak çapraz ortam seçeneği `btoa`/`atob` olacaktır.

## Aslında ne kullanılmalı

Bu makaleden yalnızca bir öneri alacaksanız, aşağıdaki üç tek satırlık kodu tercih edin. Düz ASCII metinler ve eski kod tabanları için `btoa`/`atob`'i kullanın; `toBase64()` tüm kitleyi kapsayana kadar tarayıcı yedek çözümü olarak `bytesToBase64` yardımcı fonksiyonunu tercih edin.

```js
// Modern browsers (2025+)
const enc = new TextEncoder().encode(str).toBase64();
const dec = new TextDecoder().decode(Uint8Array.fromBase64(b64));

// Browser fallback (MDN helper)
const encFallback = bytesToBase64(new TextEncoder().encode(str));

// Node (validate input first if it isn't yours)
const encNode = Buffer.from(str).toString('base64');

```

Göndermeden önce, tarayıcı aracında hızlı bir dönüşüm testiyle çıktınızı doğrulayın. `'Hello, world!'` değerini [Tool Cloud'un ücretsiz Base64 Kodlayıcı / Çözücü](https://www.tool-cloud.com/tr/dev/base64%5Fencoder/) sayfasına yapıştırın, `'SGVsbG8sIHdvcmxkIQ=='` sonucunu aldığınızdan emin olun ve ardından kodu çözerek orijinal metinle aynı olduğunu kontrol edin. Ayrıca ayrı [Metinden Base64'e dönüştürücü](https://www.tool-cloud.com/tr/general/text%5Fto%5Fbase64/) ve [Base64'ten Metne dönüştürücü](https://www.tool-cloud.com/tr/general/base64%5Fto%5Ftext/) araçları da mevcuttur; yüklenen dosyalar otomatik olarak silinir ve hiçbir şey kurmanıza gerek yoktur.

## Sıkça sorulan sorular

### Neden btoa() emoji üzerinde başarısız olurken İngilizce metinde çalışır?

btoa(), her karakteri tek bir bayt olarak ele alır ve her kod noktasının 256'nın altında olmasını gerektirir (güvenilir şekilde yalnızca 0x7F'e kadar). Emoji, vurgulu karakterler ve Çince/Korece/Japonca (CJK) metin birden fazla bayt gerektirdiğinden DOMException: InvalidCharacterError tetiklenir. Önce metni UTF-8 baytlarına dönüştürün, ardından baytları kodlayın.

### btoa() kullanımdan kaldırıldı mı?

Hayır, tarayıcılarda kullanımdan kaldırılmadı — MDN, btoa() ve atob()'yu Temmuz 2015'ten bu yana Baseline widely available (geniş çapta kullanılabilir) olarak işaretler. Ancak Node'un tür tanımları, bunları Node'a özgü kodlarda Buffer.from(str, 'base64') lehine kullanımdan kaldırılmış olarak işaretler. Bunlar kaldırılmış değil, eski (legacy) bir API'dir.

### Unicode metni (vurgular, Çince, emoji) nasıl Base64'e kodlarım?

UTF-8 baytlarını almak için new TextEncoder().encode(str) kullanın, ardından baytları kodlayın (btoa() aracılığıyla bir bayt dizisi yardımcı fonksiyonu veya modern tarayıcılarda Uint8Array.toBase64()). Baytları geri almak için çözmeye Uint8Array.fromBase64() veya atob() ile başlayın, ardından new TextDecoder().decode(bytes) ile metne çevirin.

### base64 ile base64url arasındaki fark nedir?

base64url (RFC 4648 §5), '+' ve '/' yerine '-' ve '\_' kullanır ve genellikle '=' dolgu karakterini atlar. Çıktı URL'lere veya JWT'lere gidecekse base64url kullanın; standart base64, yol parçası veya sorgu dizesi içermeyen data: URL'leri için uygundur.

### Neden Node.js geçersiz base64 için hata vermez?

Node.js'in Buffer.from(str, 'base64') yöntemi girişi doğrulamaz: geçersiz karakterleri sessizce yok sayar, bu nedenle Buffer.from('aGVsbG8!!!', 'base64').toString() 'hello' döndürür ve hata vermez. Tarayıcılarda ise atob() aynı girişte InvalidCharacterError fırlatır. Node.js'te çözümlerken güvenilmeyen base64'ü önceden doğrulayın.