Codificação/Decodificação Base64 em JavaScript: btoa(), atob() e Unicode
Codificação e Decodificação Base64 em JavaScript
JavaScript oferece várias maneiras nativas de codificar e decodificar strings Base64. Se você está criando uma aplicação de navegador ou um servidor Node.js, entender como trabalhar com Base64 é essencial para lidar com dados binários em formatos baseados em texto como JSON, HTML e URLs.
Usando btoa() e atob() no Navegador
As duas funções principais para Base64 no JavaScript de navegador são btoa() e atob(). Esses nomes de função seguem uma convenção de nomenclatura mais antiga — btoa significa "binary to ASCII" (binário para ASCII) e atob significa "ASCII to binary" (ASCII para binário). Elas são suportadas em todos os principais navegadores há décadas.
Codificando com btoa()
const originalString = 'Hello, world!';
const encoded = btoa(originalString);
console.log(encoded);
// Output: SGVsbG8sIHdvcmxkIQ==
Decodificando com atob()
const base64String = 'SGVsbG8sIHdvcmxkIQ==';
const decoded = atob(base64String);
console.log(decoded);
// Output: Hello, world!
Ambas as funções funcionam com strings que contêm apenas caracteres Latin-1 (cada caractere representado por um único byte). Esta é uma limitação importante que abordaremos a seguir.
Lidando com Unicode e Caracteres Não-ASCII
Uma armadilha comum: btoa() lança um erro quando recebe strings contendo caracteres fora do intervalo Latin-1, como emojis, caracteres chineses ou letras acentuadas.
btoa('Hello 你好');
// Error: The string to be encoded contains characters outside of the Latin-1 range.
Para codificar strings Unicode, você precisa converter a string em bytes primeiro e então codificar esses bytes. A abordagem moderna usa as APIs TextEncoder e TextDecoder:
function unicodeToBase64(str) {
const bytes = new TextEncoder().encode(str);
const binaryString = String.fromCharCode(...bytes);
return btoa(binaryString);
}
function base64ToUnicode(base64) {
const binaryString = atob(base64);
const bytes = Uint8Array.from(binaryString, (c) => c.charCodeAt(0));
return new TextDecoder().decode(bytes);
}
// Usage
const encoded = unicodeToBase64('Hello 你好 🚀');
console.log(encoded);
// Output: SGVsbG8g5L2g5aW9IPCfj4A=
const decoded = base64ToUnicode(encoded);
console.log(decoded);
// Output: Hello 你好 🚀
Uma técnica mais antiga usa encodeURIComponent e decodeURIComponent, mas a abordagem com TextEncoder/TextDecoder é mais robusta e é a solução moderna recomendada.
Codificando Dados Binários (ArrayBuffer)
Ao trabalhar com arquivos, imagens ou dados binários brutos de APIs como fetch ou FileReader, você normalmente tem um ArrayBuffer ou Uint8Array. Veja como convertê-lo para Base64:
function arrayBufferToBase64(buffer) {
const bytes = new Uint8Array(buffer);
let binaryString = '';
for (let i = 0; i < bytes.length; i++) {
binaryString += String.fromCharCode(bytes[i]);
}
return btoa(binaryString);
}
function base64ToArrayBuffer(base64) {
const binaryString = atob(base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
Convertendo um Arquivo para Base64 no Navegador
Aqui está um exemplo completo usando FileReader para converter um arquivo selecionado pelo usuário em uma data URL Base64:
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = () => reject(new Error('Failed to read file'));
reader.readAsDataURL(file);
});
}
// Usage with a file input
document.querySelector('input[type="file"]').addEventListener('change', async (e) => {
const file = e.target.files[0];
try {
const dataUrl = await fileToBase64(file);
console.log(dataUrl); // data:image/png;base64,iVBORw0KGgo...
} catch (err) {
console.error('Conversion failed:', err);
}
});
Usando Base64 em Node.js
O Node.js fornece a classe Buffer para operações Base64, que é mais flexível que o btoa/atob do navegador. A classe Buffer lida com codificação e decodificação automaticamente, incluindo Unicode, e suporta múltiplos formatos de codificação.
Codificação e Decodificação Básica
// Encode a string to Base64
const encoded = Buffer.from('Hello, world!').toString('base64');
console.log(encoded);
// Output: SGVsbG8sIHdvcmxkIQ==
// Decode a Base64 string back to text
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
console.log(decoded);
// Output: Hello, world!
Suporte a Unicode em Node.js
Ao contrário do btoa() no navegador, o Buffer do Node.js lida com Unicode sem problemas:
const encoded = Buffer.from('Hello 你好 🚀').toString('base64');
console.log(encoded);
// Output: SGVsbG8g5L2g5aW9IPCfj4A=
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
console.log(decoded);
// Output: Hello 你好 🚀
Lendo um Arquivo e Codificando como Base64
const fs = require('fs');
// Read a file and encode it to Base64
const buffer = fs.readFileSync('image.png');
const base64 = buffer.toString('base64');
const dataUrl = `data:image/png;base64,${base64}`;
Codificação Base64url em Node.js
O Node.js 15.7.0+ oferece suporte nativo à codificação Base64url, que substitui + por - e / por _ e omite o padding:
const encoded = Buffer.from('Hello, world!').toString('base64url');
console.log(encoded);
// Output: SGVsbG8sIHdvcmxkIQ (no padding)
const decoded = Buffer.from(encoded, 'base64url').toString('utf-8');
console.log(decoded);
// Output: Hello, world!
Considerações de Desempenho
Para dados grandes, operações Base64 repetidas podem ser lentas. Aqui estão algumas dicas:
- Use
TextEncoder/TextDecoderem vez de conversões manuais para strings Unicode - Em Node.js,
Buffer.from()é altamente otimizado — prefira-o em vez de implementações manuais - Evite converter arquivos grandes para Base64, a menos que seja necessário (considere streaming)
- Para conjuntos de dados grandes, considere usar
BlobeFileReaderno navegador para evitar bloquear a thread principal
Experimente a Codificação Base64 Online
Experimente codificar e decodificar direto no seu navegador usando nosso codificador e decodificador Base64 online gratuito. Não é necessário programar — basta colar um texto ou enviar um arquivo e obter o resultado Base64 instantaneamente.