Node.js-error "btoa no está definido"
(5)
Descubrí que, aunque las cuñas de las respuestas anteriores funcionaban, no coincidían con el comportamiento de las implementaciones de browsers de escritorio de btoa()
y atob()
:
const btoa = function(str){ return Buffer.from(str).toString(''base64''); }
// returns "4pyT", yet in desktop Chrome would throw an error.
btoa(''✓'');
// returns "fsO1w6bCvA==", yet in desktop Chrome would return "fvXmvA=="
btoa(String.fromCharCode.apply(null, new Uint8Array([0x7e, 0xf5, 0xe6, 0xbc])));
Como resultado, las instancias de Buffer
representan / interpretan cadenas codificadas en UTF-8 de manera predeterminada . Por el contrario, en el escritorio de Chrome, ni siquiera puede ingresar una cadena que contenga caracteres fuera del rango de btoa()
en btoa()
, ya que arrojará una excepción Uncaught DOMException: Failed to execute ''btoa'' on ''Window'': The string to be encoded contains characters outside of the Latin1 range.
Por lo tanto, debe establecer explícitamente el tipo de codificación en latin1
para que su shin de Node.js coincida con el tipo de codificación del escritorio de Chrome:
const btoaLatin1 = function(str) { return Buffer.from(str, ''latin1'').toString(''base64''); }
const atobLatin1 = function(b64Encoded) {return Buffer.from(b64Encoded, ''base64'').toString(''latin1'');}
const btoaUTF8 = function(str) { return Buffer.from(str, ''utf8'').toString(''base64''); }
const atobUTF8 = function(b64Encoded) {return Buffer.from(b64Encoded, ''base64'').toString(''utf8'');}
btoaLatin1(''✓''); // returns "Ew==" (would be preferable for it to throw error because this is undecodable)
atobLatin1(btoa(''✓'')); // returns "/u0019" (END OF MEDIUM)
btoaUTF8(''✓''); // returns "4pyT"
atobUTF8(btoa(''✓'')); // returns "✓"
// returns "fvXmvA==", just like desktop Chrome
btoaLatin1(String.fromCharCode.apply(null, new Uint8Array([0x7e, 0xf5, 0xe6, 0xbc])));
// returns "fsO1w6bCvA=="
btoaUTF8(String.fromCharCode.apply(null, new Uint8Array([0x7e, 0xf5, 0xe6, 0xbc])));
En mi aplicación node.js hice una npm install btoa-atob
para poder usar las funciones btoa () y atob () que son nativas en javascript del lado del cliente pero que por alguna razón no fueron incluidas en el nodo. El nuevo directorio apareció en mi carpeta node_modules, que está en la raíz junto con app.js. Luego me aseguré de agregar btoa-atob como una dependencia en mi archivo package.json que está en la raíz.
Sin embargo, por alguna razón, todavía no funcionará.
console.log(btoa("Hello World!"));
^ debería generar "SGVsbG8gV29ybGQh" en la consola, pero en su lugar aparece el error "btoa is not defiend".
¿No hice la instalación correctamente? ¿Qué pasé por alto?
El módulo ''btoa-atob'' no exporta una interfaz programática, solo proporciona utilidades de línea de comandos.
Si necesita convertir a Base64, puede hacerlo con Buffer:
console.log(Buffer.from(''Hello World!'').toString(''base64''));
Invertir (suponiendo que el contenido que está decodificando es una cadena utf8):
console.log(Buffer.from(b64Encoded, ''base64'').toString());
Nota: antes del Nodo v4, use el new Buffer
lugar de Buffer.from
.
Entiendo que este es un punto de discusión para una aplicación de nodos, pero en interés de las aplicaciones universales de JavaScript que se ejecutan en un servidor de nodos, que es cómo llegué a esta publicación, he estado investigando esto para una aplicación de reacción universal / isomorfa que he estado construyendo, y el paquete abab
funcionó para mí. De hecho, fue la única solución que pude encontrar que funcionó, en lugar de usar el método Buffer también mencionado (tuve problemas de mecanografía).
(Este paquete es utilizado por jsdom
, que a su vez es utilizado por el paquete de window
).
Volviendo a mi punto; basado en esto, quizás si esta funcionalidad ya está escrita como un paquete npm como el que mencionaste, y tiene su propio algoritmo basado en la especificación W3, podrías instalar y usar el paquete abab
lugar de escribir tu propia función que puede o no ser preciso en función de la codificación.
--- EDITAR ---
Empecé a tener problemas extraños hoy con la codificación (no estoy seguro de por qué comenzó a suceder ahora) con el paquete abab
. Parece codificar correctamente la mayor parte del tiempo, pero a veces en la interfaz codifica incorrectamente. Pasé mucho tiempo intentando depurar, pero cambié al paquete base-64
como se recomienda, y funcionó de inmediato. Definitivamente parecía depender del algoritmo base64 de abab
.
Las soluciones publicadas aquí no funcionan en caracteres que no sean Ascii si planea intercambiar Base64 entre Node.js y un navegador. Para que funcione, debe marcar el texto de entrada como ''binario''.
Buffer.from(''Hélló wórld!!'', ''binary'').toString(''base64'')
Esto le da SOlsbPMgd/NybGQhIQ==
. Si atob(''SOlsbPMgd/NybGQhIQ=='')
en un navegador, lo decodificará de la manera correcta. Lo hará bien también en Node.js a través de:
Buffer.from(''SOlsbPMgd/NybGQhIQ=='', ''base64'').toString(''binary'')
Si no hace la "parte binaria", decodificará erróneamente los caracteres especiales.
Lo obtuve de la implementación del paquete btoa npm :
Mi equipo se encontró con este problema al usar Node con React Native y PouchDB. Así es como lo resolvimos ...
NPM install buffer:
$ npm install --save buffer
Asegúrese de que Buffer
, btoa
y atob
estén cargados como globales:
global.Buffer = global.Buffer || require(''buffer'').Buffer;
if (typeof btoa === ''undefined'') {
global.btoa = function (str) {
return new Buffer(str, ''binary'').toString(''base64'');
};
}
if (typeof atob === ''undefined'') {
global.atob = function (b64Encoded) {
return new Buffer(b64Encoded, ''base64'').toString(''binary'');
};
}