Base64 w JavaScript — btoa() i Buffer
Użyj darmowego Koder Base64 Online bezpośrednio w przeglądarce — bez instalacji.
Wypróbuj Koder Base64 Online online →Kiedy osadzasz obraz w CSS data URI, przekazujesz poświadczenia w nagłówku HTTP Authorization lub przechowujesz binarny certyfikat w zmiennej środowiskowej, musisz niezawodnie kodować dane JavaScript w Base64 zarówno w przeglądarce, jak i Node.js. JavaScript udostępnia dwa odrębne wbudowane API:btoa() dla środowisk przeglądarkowych (dostępne też w Node.js 16+) oraz Buffer.from() dla Node.js — każde z różnymi ograniczeniami dotyczącymi Unicode, danych binarnych i bezpieczeństwa URL. Aby szybko zakodować dane bez pisania kodu, ToolDeck's Base64 Encoder obsługuje to natychmiast w przeglądarce. Ten przewodnik obejmuje oba środowiska z przykładami gotowymi do produkcji: obsługa Unicode, warianty URL-bezpieczne, kodowanie plików i odpowiedzi API, użycie CLI i cztery błędy, które konsekwentnie powodują problemy w rzeczywistych bazach kodu.
- ✓btoa() jest wbudowane w przeglądarkę i dostępne globalnie w Node.js 16+, ale akceptuje tylko Latin-1 (punkty kodowe 0–255) — wejście Unicode rzuca DOMException
- ✓Buffer.from(text, "utf8").toString("base64") to odpowiednik Node.js, który natywnie obsługuje Unicode bez dodatkowych kroków
- ✓URL-bezpieczny Base64 zastępuje + na -, / na _ i usuwa padding = — w Node.js 18+ użyj Buffer.from().toString("base64url") jako jednolinijkowe rozwiązanie
- ✓Dla danych binarnych (ArrayBuffer, Uint8Array, pliki) użyj Buffer w Node.js lub podejścia arrayBuffer() + Uint8Array w przeglądarce — nigdy response.text()
- ✓Uint8Array.prototype.toBase64() (TC39 Stage 3) jest już dostępne w Node.js 22+ i Chrome 130+ i ujednolici oba środowiska
Czym jest kodowanie Base64?
Base64 konwertuje dowolne dane binarne na ciąg znaków zbudowany z 64 drukowalnych znaków ASCII: A–Z, a–z, 0–9, + i /. Każde 3 bajty wejścia mapują się dokładnie na 4 znaki Base64; jeśli długość wejścia nie jest wielokrotnością 3, dodawane są jeden lub dwa znaki wypełnienia =. Zakodowane wyjście jest zawsze o około 33% większe niż oryginał.
Base64 to nie szyfrowanie — nie zapewnia poufności. Każdy, kto posiada zakodowany ciąg, może go zdekodować jednym wywołaniem funkcji. Jego celem jest bezpieczeństwo transportu: wiele protokołów i formatów przechowywania zostało zaprojektowanych dla 7-bitowego tekstu ASCII i nie może obsługiwać dowolnych bajtów binarnych. Base64 wypełnia tę lukę. Typowe przypadki użycia JavaScript obejmują data URI do wstawiania zasobów, nagłówki HTTP Basic Auth, segmenty tokenów JWT, załączniki MIME w e-mailach i przechowywanie binarnych obiektów blob w API JSON.
deploy-bot:sk-prod-a7f2c91e4b3d8
ZGVwbG95LWJvdDpzay1wcm9kLWE3ZjJjOTFlNGIzZDg=
btoa() — natywna funkcja kodowania przeglądarki
btoa() (binary-to-ASCII) jest dostępna w przeglądarkach od IE10 i stała się globalną funkcją w Node.js 16.0 jako część inicjatywy zgodności WinterCG. Działa też natywnie w Deno, Bun i Cloudflare Workers. Nie wymaga importu.
Funkcja przyjmuje jeden argument łańcuchowy i zwraca jego zakodowaną formę Base64. Symetryczny odpowiednik atob() (ASCII-to-binary) dekoduje z powrotem. Obie są synchroniczne i działają przy stałej pamięci względem rozmiaru wejścia.
Minimalny działający przykład
// Encoding an API credential pair for an HTTP Basic Auth header
const serviceId = 'deploy-bot'
const apiKey = 'sk-prod-a7f2c91e4b3d8'
const credential = btoa(`${serviceId}:${apiKey}`)
// → 'ZGVwbG95LWJvdDpzay1wcm9kLWE3ZjJjOTFlNGIzZDg='
const headers = new Headers({
Authorization: `Basic ${credential}`,
'Content-Type': 'application/json',
})
console.log(headers.get('Authorization'))
// Basic ZGVwbG95LWJvdDpzay1wcm9kLWE3ZjJjOTFlNGIzZDg=Dekodowanie za pomocą atob()
// Round-trip: encode, transmit, decode const payload = 'service:payments region:eu-west-1 env:production' const encoded = btoa(payload) const decoded = atob(encoded) console.log(encoded) // c2VydmljZTpwYXltZW50cyByZWdpb246ZXUtd2VzdC0xIGVudjpwcm9kdWN0aW9u console.log(decoded === payload) // true
btoa() i atob() są częścią WinterCG Minimum Common API — tej samej specyfikacji, która reguluje Fetch, URL i crypto w środowiskach innych niż przeglądarka. Zachowują się identycznie w Node.js 16+, Bun, Deno i Cloudflare Workers.Obsługa Unicode i znaków spoza ASCII
Najczęstszą pułapką btoa() jest jej ścisła granica Latin-1. Każdy znak z punktem kodowym powyżej U+00FF powoduje natychmiastowy wyjątek:
btoa('Müller & Søren') // ❌ Uncaught DOMException: String contains an invalid character
btoa('résumé') // ❌ 'é' is U+00E9 = 233 — within Latin-1, this one actually works
btoa('田中太郎') // ❌ Throws — all CJK characters are above U+00FFPrawidłowe podejście to zakodowanie ciągu do bajtów UTF-8 najpierw, a następnie zakodowanie tych bajtów w Base64. JavaScript dostarcza TextEncoder dokładnie do tego celu:
Podejście TextEncoder — bezpieczne dla dowolnego wejścia Unicode
// Utility functions for Unicode-safe Base64
function toBase64(text: string): string {
const bytes = new TextEncoder().encode(text)
const chars = Array.from(bytes, byte => String.fromCharCode(byte))
return btoa(chars.join(''))
}
function fromBase64(encoded: string): string {
const binary = atob(encoded)
const bytes = Uint8Array.from(binary, ch => ch.charCodeAt(0))
return new TextDecoder().decode(bytes)
}
// Works with any language or script
const orderNote = 'Potwierdzono: Piotr Kowalski — magazyn Warszawa, ilość: 250'
const encoded = toBase64(orderNote)
const decoded = fromBase64(encoded)
console.log(encoded)
// UG90d2llcmR6b25vOiBQaW90ciBLb3dhbHNraSDigJQgbWFnYXp5biBXYXJzemF3YSwgaWzDn8WTxIc6IDI1MA==
console.log(decoded === orderNote) // trueBuffer.from(text, 'utf8').toString('base64'). Obsługuje Unicode natywnie i jest szybszy dla dużych ciągów.Buffer.from() w Node.js — kompletny przewodnik z przykładami
W Node.js Buffer jest idiomatycznym API dla wszystkich operacji na danych binarnych, w tym konwersji kodowania. Poprzedza TextEncoder o lata i pozostaje preferowanym wyborem dla kodu po stronie serwera. Kluczowe zalety nad btoa(): natywna obsługa UTF-8, obsługa danych binarnych i skrót kodowania 'base64url' dostępny od Node.js 18.
Podstawowe kodowanie i dekodowanie tekstu
// Encoding a server configuration object for storage in an env variable
const dbConfig = JSON.stringify({
host: 'db-primary.internal',
port: 5432,
database: 'analytics_prod',
maxConnections: 100,
ssl: { rejectUnauthorized: true },
})
const encoded = Buffer.from(dbConfig, 'utf8').toString('base64')
console.log(encoded)
// eyJob3N0IjoiZGItcHJpbWFyeS5pbnRlcm5hbCIsInBvcnQiOjU0MzIsImRhdGFiYXNlIjoiYW5h...
// Decoding back
const decoded = Buffer.from(encoded, 'base64').toString('utf8')
const config = JSON.parse(decoded)
console.log(config.host) // db-primary.internal
console.log(config.maxConnections) // 100Kodowanie plików binarnych z dysku
import { readFileSync, writeFileSync } from 'node:fs'
import { join } from 'node:path'
// Read a TLS certificate and encode it for embedding in a config file
const certPem = readFileSync(join(process.cwd(), 'ssl', 'server.crt'))
const certBase64 = certPem.toString('base64')
// Store as a single-line string — suitable for env vars or JSON configs
writeFileSync('./dist/cert.b64', certBase64, 'utf8')
console.log(`Certificate encoded: ${certBase64.length} characters`)
// Certificate encoded: 2856 characters
// Restore the binary cert from the encoded value
const restored = Buffer.from(certBase64, 'base64')
console.log(restored.equals(certPem)) // trueAsynchroniczne kodowanie pliku z obsługą błędów
import { readFile } from 'node:fs/promises'
async function encodeFileToBase64(filePath: string): Promise<string> {
try {
const buffer = await readFile(filePath)
return buffer.toString('base64')
} catch (err) {
const code = (err as NodeJS.ErrnoException).code
if (code === 'ENOENT') throw new Error(`File not found: ${filePath}`)
if (code === 'EACCES') throw new Error(`Permission denied: ${filePath}`)
throw err
}
}
// Encode a PDF for an email attachment payload
const reportBase64 = await encodeFileToBase64('./reports/q1-financials.pdf')
const emailPayload = {
to: 'finance-team@company.internal',
subject: 'Q1 Financial Report',
attachments: [{
filename: 'q1-financials.pdf',
content: reportBase64,
encoding: 'base64',
contentType: 'application/pdf',
}],
}
console.log(`Attachment: ${reportBase64.length} chars`)Funkcje Base64 JavaScript — dokumentacja parametrów
W przeciwieństwie do modułu base64 Pythona, JavaScript nie ma jednej zunifikowanej funkcji Base64. API zależy od środowiska docelowego. Oto kompletna dokumentacja dla wszystkich natywnych podejść:
| Funkcja | Typ wejścia | Unicode | URL-bezpieczny | Dostępny w |
|---|---|---|---|---|
| btoa(string) | string (Latin-1) | ❌ rzuca powyżej U+00FF | ❌ ręczne zastępowanie | Browser, Node 16+, Bun, Deno |
| atob(string) | Base64 string | ❌ zwraca ciąg binarny | ❌ ręczne zastępowanie | Browser, Node 16+, Bun, Deno |
| Buffer.from(src, enc) .toString(enc) | string | Buffer | Uint8Array | ✅ kodowanie utf8 | ✅ base64url w Node 18+ | Node.js, Bun |
| TextEncoder().encode(str) + btoa() | string (dowolny Unicode) | ✅ przez bajty UTF-8 | ❌ ręczne zastępowanie | Browser, Node 16+, Deno |
| Uint8Array.toBase64() (TC39) | Uint8Array | ✅ binarny | ✅ omitPadding + alphabet | Chrome 130+, Node 22+ |
Sygnatura Buffer.from(src, enc).toString(enc) akceptuje kilka wartości kodowania istotnych dla Base64:
URL-bezpieczny Base64 — kodowanie dla JWT, URL i nazw plików
Standardowy Base64 używa + i /, które są zarezerwowane w URL — + jest dekodowany jako spacja w ciągach zapytań, a / jest separatorem ścieżek. JWT, parametry URL, nazwy plików i wartości cookie wymagają wariantu URL-bezpiecznego: + → -, / → _, usunięcie końcowego =.
Przeglądarka — ręczne zastępowanie znaków
function toBase64Url(text: string): string {
// For ASCII-safe input (e.g., JSON with only ASCII chars)
return btoa(text)
.replace(/+/g, '-')
.replace(///g, '_')
.replace(/=/g, '')
}
function fromBase64Url(encoded: string): string {
// Restore standard Base64 characters and padding before decoding
const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/')
const padded = base64 + '==='.slice(0, (4 - base64.length % 4) % 4)
return atob(padded)
}
// JWT header — must be URL-safe Base64
const header = JSON.stringify({ alg: 'HS256', typ: 'JWT' })
const encoded = toBase64Url(header)
console.log(encoded) // eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
const decoded = fromBase64Url(encoded)
console.log(decoded) // {"alg":"HS256","typ":"JWT"}Node.js 18+ — natywne kodowanie 'base64url'
// Node.js 18 added 'base64url' as a first-class Buffer encoding
const sessionPayload = JSON.stringify({
userId: 'usr_9f2a1c3e8b4d',
role: 'editor',
workspaceId:'ws_3a7f91c2',
exp: Math.floor(Date.now() / 1000) + 3600,
})
const encoded = Buffer.from(sessionPayload, 'utf8').toString('base64url')
// No + or / or = characters in the output
// eyJ1c2VySWQiOiJ1c3JfOWYyYTFjM2U4YjRkIiwicm9sZSI6ImVkaXRvciIsIndvcmtzcGFjZUlkIjoid3NfM2E3ZjkxYzIiLCJleHAiOjE3MTcyMDM2MDB9
const decoded = Buffer.from(encoded, 'base64url').toString('utf8')
console.log(JSON.parse(decoded).role) // editorKodowanie plików i odpowiedzi API w JavaScript
W kodzie produkcyjnym kodowanie Base64 jest najczęściej stosowane do przesyłanych plików i odpowiedzi z zewnętrznych API dostarczających zawartość binarną. Wzorce różnią się między przeglądarką a Node.js, a dane binarne wymagają szczególnej uwagi.
Przeglądarka — kodowanie pliku z elementu input
// Modern approach: File.arrayBuffer() (Chrome 76+, Firefox 69+, Safari 14+)
async function encodeFile(file: File): Promise<string> {
const buffer = await file.arrayBuffer()
const bytes = new Uint8Array(buffer)
const chars = Array.from(bytes, b => String.fromCharCode(b))
return btoa(chars.join(''))
}
const uploadInput = document.getElementById('avatar') as HTMLInputElement
uploadInput.addEventListener('change', async (e) => {
const file = (e.target as HTMLInputElement).files?.[0]
if (!file) return
try {
const encoded = await encodeFile(file)
const dataUri = `data:${file.type};base64,${encoded}`
// Preview the image inline
const img = document.getElementById('preview') as HTMLImageElement
img.src = dataUri
img.hidden = false
console.log(`Encoded ${file.name} (${file.size} bytes) → ${encoded.length} Base64 chars`)
} catch (err) {
console.error('Encoding failed:', err)
}
})Pobieranie binarnych danych zakodowanych w Base64 z API
// GitHub Contents API returns file content as Base64 with embedded newlines
async function fetchRepoFile(
owner: string,
repo: string,
path: string,
token: string,
): Promise<string> {
const res = await fetch(
`https://api.github.com/repos/${owner}/${repo}/contents/${path}`,
{
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/vnd.github.v3+json',
},
}
)
if (!res.ok) throw new Error(`GitHub API ${res.status}: ${res.statusText}`)
const data = await res.json() as { content: string; encoding: string; size: number }
if (data.encoding !== 'base64') {
throw new Error(`Unexpected encoding from GitHub: ${data.encoding}`)
}
// GitHub wraps output at 60 chars — strip newlines before decoding
const clean = data.content.replace(/\n/g, '')
return atob(clean)
}
const openApiSpec = await fetchRepoFile(
'acme-corp', 'platform-api', 'openapi.json', process.env.GITHUB_TOKEN!
)
const spec = JSON.parse(openApiSpec)
console.log(`API version: ${spec.info.version}`)Kiedy podczas debugowania API chcesz sprawdzić zakodowaną odpowiedź bez pisania skryptu, wklej wartość Base64 bezpośrednio do Base64 Encoder — obsługuje też dekodowanie z natychmiastowym wynikiem. Przydatne do sprawdzania odpowiedzi GitHub API, ładunków JWT i podpisów webhook.
Kodowanie Base64 w wierszu poleceń w Node.js i powłoce
Do skryptów CI/CD, celów Makefile lub jednorazowego debugowania rzadko potrzebujesz pełnego skryptu. Zarówno narzędzia systemowe, jak i jednolinijkowce Node.js pokrywają większość przypadków na różnych platformach.
# ── macOS / Linux system base64 ───────────────────────────────────────
# Standard encoding
echo -n "deploy-bot:sk-prod-a7f2c91e4b3d8" | base64
# ZGVwbG95LWJvdDpzay1wcm9kLWE3ZjJjOTFlNGIzZDg=
# URL-safe variant (replace chars and strip padding)
echo -n "deploy-bot:sk-prod-a7f2c91e4b3d8" | base64 | tr '+/' '-_' | tr -d '='
# Encode a file inline (macOS: -b 0 removes line wrapping; Linux: --wrap=0)
base64 -b 0 ./config/production.json
# or on Linux:
base64 --wrap=0 ./config/production.json
# Decode
echo "ZGVwbG95LWJvdDpzay1wcm9kLWE3ZjJjOTFlNGIzZDg=" | base64 --decode
# ── Node.js one-liner — works on Windows too ───────────────────────────
node -e "process.stdout.write(Buffer.from(process.argv[1]).toString('base64'))" "my:secret"
# bXk6c2VjcmV0
# URL-safe from Node.js 18+
node -e "process.stdout.write(Buffer.from(process.argv[1]).toString('base64url'))" "my:secret"
# bXk6c2VjcmV0 (same here since there are no special chars)
# Decode in Node.js
node -e "console.log(Buffer.from(process.argv[1], 'base64').toString())" "ZGVwbG95LWJvdA=="base64 domyślnie zawija wyjście po 76 znakach. Powoduje to błędy w dalszym parsowaniu. Zawsze dodawaj -b 0 (macOS) lub --wrap=0 (Linux), gdy potrzebujesz wyniku w jednej linii — na przykład przy zapisywaniu do zmiennej środowiskowej lub pola konfiguracyjnego.Wysokowydajna alternatywa: js-base64
Wbudowane API są wystarczające dla większości przypadków. Głównym powodem sięgania po bibliotekę jest spójność między środowiskami: jeśli publikujesz pakiet działający zarówno w przeglądarce, jak i Node.js, użycie Buffer wymaga wykrywania środowiska lub konfiguracji bundlera, podczas gdy btoa() wymaga obejścia Unicode. js-base64 (ponad 100M tygodniowych pobrań z npm) obsługuje oba transparentnie.
npm install js-base64 # or pnpm add js-base64
import { toBase64, fromBase64, toBase64Url, fromBase64Url, isValid } from 'js-base64'
// Standard encoding — Unicode-safe, works in browser and Node.js
const telemetryEvent = JSON.stringify({
eventId: 'evt_7c3a9f1b2d',
type: 'checkout_completed',
currency: 'EUR',
amount: 14900,
userId: 'usr_4e2b8d6a5c',
timestamp: 1717200000,
})
const encoded = toBase64(telemetryEvent)
const urlEncoded = toBase64Url(telemetryEvent) // No +, /, or = characters
const decoded = fromBase64(encoded)
console.log(JSON.parse(decoded).type) // checkout_completed
// Binary data — pass a Uint8Array as second argument
const pngMagicBytes = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])
const binaryEncoded = toBase64(pngMagicBytes, true) // true = binary mode
// Validation before decoding
const suspicious = 'not!valid@base64#'
console.log(isValid(suspicious)) // falsePod spodem js-base64 używa natywnego Buffer, gdy jest dostępny, i wraca do czystej implementacji JS w przeglądarce. Jest 2–3× szybszy niż podejście TextEncoder+btoa dla dużych ciągów Unicode, a symetryczne API (toBase64 / fromBase64) eliminuje konieczność pamiętania kierunku btoa i atob.
Kodowanie dużych plików binarnych przy użyciu strumieni Node.js
Gdy musisz kodować pliki większe niż ~50 MB, ładowanie całego pliku do pamięci za pomocą readFileSync() staje się problemem. Strumienie Node.js pozwalają przetwarzać dane w kawałkach — ale kodowanie Base64 ma ograniczenie: musisz podawać enkoderu wielokrotności 3 bajtów, aby uniknąć nieprawidłowego paddingu na granicach kawałków.
import { createReadStream, createWriteStream } from 'node:fs'
import { pipeline } from 'node:stream/promises'
// Stream a large binary file to a Base64-encoded output file
async function streamEncodeToBase64(
inputPath: string,
outputPath: string,
): Promise<void> {
const readStream = createReadStream(inputPath, { highWaterMark: 3 * 1024 * 256 }) // 768 KB chunks (multiple of 3)
const writeStream = createWriteStream(outputPath, { encoding: 'utf8' })
let buffer = Buffer.alloc(0)
await pipeline(
readStream,
async function* (source) {
for await (const chunk of source) {
buffer = Buffer.concat([buffer, chunk as Buffer])
// Encode in complete 3-byte groups to avoid mid-stream padding
const remainder = buffer.length % 3
const safe = buffer.subarray(0, buffer.length - remainder)
buffer = buffer.subarray(buffer.length - remainder)
if (safe.length > 0) yield safe.toString('base64')
}
// Flush remaining bytes (may add 1 or 2 '=' padding chars)
if (buffer.length > 0) yield buffer.toString('base64')
},
writeStream,
)
}
// Usage: encode a 200 MB video attachment
await streamEncodeToBase64(
'./uploads/product-demo.mp4',
'./dist/product-demo.b64',
)
console.log('Stream encoding complete')= w środku wyjścia. Przykład używa 3 * 1024 * 256 = 786 432 bajtów (768 KB) — dostosuj highWaterMark zależnie od budżetu pamięci. Dla plików poniżej 50 MB, readFile() + Buffer.toString('base64') jest prostsze i wystarczająco szybkie.Typowe błędy
Przejrzałem wiele baz kodu JavaScript z kodowaniem Base64 i te cztery błędy pojawiają się konsekwentnie — często nieodkryte aż do momentu, gdy znak spoza ASCII lub plik binarny trafi na ścieżkę kodowania w produkcji.
Błąd 1 — Przekazanie Unicode bezpośrednio do btoa()
Problem: btoa() akceptuje tylko znaki z punktami kodowymi 0–255. Znaki takie jak ñ, emoji lub ideografy CJK powodują natychmiastowy DOMException. Rozwiązanie: zakoduj najpierw za pomocą TextEncoder lub użyj Buffer.from(text, 'utf8').toString('base64') w Node.js.
// ❌ DOMException: The string to be encoded contains // characters outside of the Latin1 range const username = 'Алексей Иванов' const encoded = btoa(username) // throws
// ✅ Encode as UTF-8 bytes first
function safeEncode(text: string): string {
const bytes = new TextEncoder().encode(text)
const chars = Array.from(bytes, b => String.fromCharCode(b))
return btoa(chars.join(''))
}
const encoded = safeEncode('Алексей Иванов')
// 0JDQu9C10LrRgdC10Lkg0JjQstCw0L3QvtCyBłąd 2 — Zapomnienie o przywróceniu paddingu przed atob()
Problem: URL-bezpieczny Base64 usuwa padding =. Przekazanie ciągu bez paddingu bezpośrednio do atob() daje nieprawidłowe wyjście lub rzuca wyjątek w zależności od długości ciągu. Rozwiązanie: przywróć + i / i dodaj właściwą ilość paddingu przed wywołaniem atob().
// ❌ atob() may return wrong data or throw // on URL-safe Base64 without padding const jwtSegment = 'eyJ1c2VySWQiOiJ1c3JfOWYyYTFjM2UifQ' const decoded = atob(jwtSegment) // Unreliable
// ✅ Restore characters and padding first
function decodeBase64Url(input: string): string {
const b64 = input.replace(/-/g, '+').replace(/_/g, '/')
const pad = b64 + '==='.slice(0, (4 - b64.length % 4) % 4)
return atob(pad)
}
const decoded = decodeBase64Url('eyJ1c2VySWQiOiJ1c3JfOWYyYTFjM2UifQ')
// {"userId":"usr_9f2a1c3e"}Błąd 3 — Łączenie zakodowanych kawałków zamiast surowych buforów
Problem: Każde wywołanie btoa() lub .toString('base64') dodaje własny padding. Łączenie dwóch ciągów Base64 z paddingiem daje nieprawidłowe wyjście, ponieważ padding należy tylko na samym końcu. Rozwiązanie: połącz surowe dane przed kodowaniem.
// ❌ Both parts are padded independently —
// the combined string is not valid Base64
const part1 = Buffer.from('webhook-secret').toString('base64')
// d2ViaG9vay1zZWNyZXQ= ← has padding
const part2 = Buffer.from('-v2').toString('base64')
// LXYy ← correct in isolation
const combined = part1 + part2 // ❌ Invalid — padding in the middle// ✅ Concatenate raw Buffers before encoding
const combined = Buffer.concat([
Buffer.from('webhook-secret'),
Buffer.from('-v2'),
]).toString('base64')
// d2ViaG9vay1zZWNyZXQtdjI= — single valid Base64 stringBłąd 4 — Użycie response.text() do odczytu binarnych danych API przed kodowaniem
Problem: response.text() interpretuje surowe bajty jako UTF-8 i zastępuje nierozpoznane sekwencje bajtów znakiem zastępczym U+FFFD. Dowolna zawartość binarna — obrazy, PDF-y, audio — jest po cichu uszkadzana zanim dotrze do btoa(). Rozwiązanie: użyj response.arrayBuffer() aby uzyskać surowe bajty.
// ❌ response.text() corrupts binary data
const res = await fetch('/api/exports/invoice.pdf')
const text = await res.text() // ❌ PDF bytes mangled as UTF-8
const encoded = btoa(text) // ❌ Corrupted Base64// ✅ arrayBuffer() preserves raw bytes
const res = await fetch('/api/exports/invoice.pdf')
const buffer = await res.arrayBuffer()
const bytes = new Uint8Array(buffer)
const chars = Array.from(bytes, b => String.fromCharCode(b))
const encoded = btoa(chars.join('')) // ✅ Valid Base64Metody Base64 JavaScript — szybkie porównanie
| Metoda | Unicode | Dane binarne | URL-bezpieczny | Środowiska | Wymaga instalacji |
|---|---|---|---|---|---|
| btoa() / atob() | ❌ Latin-1 | ❌ obejście wymagane | ❌ ręczne zastępowanie | Browser, Node 16+, Bun, Deno | Nie |
| TextEncoder + btoa() | ✅ UTF-8 | ✅ przez Uint8Array | ❌ ręczne zastępowanie | Browser, Node 16+, Deno | Nie |
| Buffer.from().toString() | ✅ utf8 | ✅ natywne | ✅ base64url (Node 18+) | Node.js, Bun | Nie |
| Uint8Array.toBase64() (TC39) | ✅ binarne | ✅ natywne | ✅ opcja alphabet | Chrome 130+, Node 22+ | Nie |
| js-base64 | ✅ zawsze | ✅ Uint8Array | ✅ wbudowane | Uniwersalne | npm install |
Wybierz btoa() tylko wtedy, gdy wejście jest potwierdzenie wyłącznie ASCII — skróty szesnastkowe, identyfikatory numeryczne lub wcześniej zweryfikowane ciągi Latin-1. Dla tekstu dostarczonego przez użytkownika w przeglądarce używaj TextEncoder + btoa(). Dla całego kodu po stronie serwera Node.js Buffer jest właściwym domyślnym wyborem. Dla bibliotek, które muszą działać w obu środowiskach bez konfiguracji bundlera, js-base64 eliminuje wszystkie przypadki brzegowe.
Często zadawane pytania
Powiązane narzędzia
Aby jednym kliknięciem zakodować lub zdekodować bez pisania kodu, wklej ciąg lub dane binarne bezpośrednio do Base64 Encoder — obsługuje tryb standardowy i URL-bezpieczny natychmiast w przeglądarce.
Alex is a front-end and Node.js developer with extensive experience building web applications and developer tooling. He is passionate about web standards, browser APIs, and the JavaScript ecosystem. In his spare time he contributes to open-source projects and writes about modern JavaScript patterns, performance optimisation, and everything related to the web platform.
Sophie is a full-stack developer focused on TypeScript across the entire stack — from React frontends to Express and Fastify backends. She has a particular interest in type-safe API design, runtime validation, and the patterns that make large JavaScript codebases stay manageable. She writes about TypeScript idioms, Node.js internals, and the ever-evolving JavaScript module ecosystem.