🔐
← Volver a guías

Codificación/decodificación Base64 en JavaScript: btoa(), atob() y Unicode

· Etiquetas: javascript, base64, btoa, atob, nodejs, encoding, web-development

Codificación y decodificación Base64 en JavaScript

JavaScript proporciona varias formas integradas de codificar y decodificar cadenas Base64. Ya sea que estés creando una aplicación de navegador o un servidor Node.js, entender cómo trabajar con Base64 es esencial para manejar datos binarios en formatos basados en texto como JSON, HTML y URLs.

Uso de btoa() y atob() en el Navegador

Las dos funciones principales para Base64 en JavaScript de navegador son btoa() y atob(). Estos nombres de función siguen una convención de nomenclatura más antigua — btoa significa "binary to ASCII" (binario a ASCII) y atob significa "ASCII to binary" (ASCII a binario). Han sido compatibles con todos los navegadores principales durante décadas.

Codificación con btoa()

const originalString = 'Hello, world!';
const encoded = btoa(originalString);
console.log(encoded);
// Output: SGVsbG8sIHdvcmxkIQ==

Decodificación con atob()

const base64String = 'SGVsbG8sIHdvcmxkIQ==';
const decoded = atob(base64String);
console.log(decoded);
// Output: Hello, world!

Ambas funciones funcionan con cadenas que contienen solo caracteres Latin-1 (cada carácter representado por un solo byte). Esta es una limitación importante que abordaremos a continuación.

Manejo de caracteres Unicode y no ASCII

Un error común: btoa() lanza un error cuando se le dan cadenas que contienen caracteres fuera del rango Latin-1, como emoji, caracteres chinos o letras acentuadas.

btoa('Hello 你好');
// Error: The string to be encoded contains characters outside of the Latin-1 range.

Para codificar cadenas Unicode, necesitas convertir primero la cadena a bytes y luego codificar esos bytes. El enfoque moderno utiliza las APIs TextEncoder y 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 你好 🚀

Una técnica más antigua utiliza encodeURIComponent y decodeURIComponent, pero el enfoque TextEncoder/TextDecoder es más robusto y es la solución moderna recomendada.

Codificación de datos binarios (ArrayBuffer)

Cuando trabajas con archivos, imágenes o datos binarios en bruto de APIs como fetch o FileReader, normalmente tienes un ArrayBuffer o Uint8Array. Así es como convertirlo a 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;
}

Conversión de un archivo a Base64 en el navegador

Aquí tienes un ejemplo completo que utiliza FileReader para convertir un archivo seleccionado por el usuario en una 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);
  }
});

Uso de Base64 en Node.js

Node.js proporciona la clase Buffer para operaciones Base64, que es más flexible que btoa/atob del navegador. La clase Buffer maneja la codificación y decodificación automáticamente, incluido Unicode, y admite múltiples formatos de codificación.

Codificación y decodificación básicas

// 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!

Soporte Unicode en Node.js

A diferencia de btoa() en el navegador, Buffer de Node.js maneja Unicode sin 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 你好 🚀

Lectura de un archivo y codificación 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}`;

Codificación Base64url en Node.js

Node.js 15.7.0+ admite codificación Base64url nativa, que reemplaza + por - y / por _ y omite el relleno:

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!

Consideraciones de rendimiento

Para datos grandes, las operaciones Base64 repetidas pueden ser lentas. Aquí tienes algunos consejos:

  • Utiliza TextEncoder/TextDecoder en lugar de conversiones manuales para cadenas Unicode
  • En Node.js, Buffer.from() está altamente optimizado — prefíerelo sobre implementaciones manuales
  • Evita convertir archivos grandes a Base64 a menos que sea necesario (considera la transmisión por flujos)
  • Para conjuntos de datos grandes, considera usar Blob y FileReader en el navegador para evitar bloquear el hilo principal

Prueba la codificación Base64 en línea

Experimenta con la codificación y decodificación directamente en tu navegador usando nuestro codificador y decodificador Base64 gratuito en línea. No se requiere programación — solo pega texto o sube un archivo y obtén el resultado Base64 al instante.