436 Stimmen

Node.js wirft den Fehler "btoa ist nicht definiert" aus

In meiner node.js-Anwendung habe ich ein npm install btoa-atob durchgeführt, damit ich die Funktionen btoa() und atob() verwenden konnte, die in clientseitigem Javascript nativ sind, aber aus irgendeinem Grund nicht in Node enthalten waren. Das neue Verzeichnis erschien in meinem node_modules-Ordner, der sich im Stammverzeichnis neben app.js befindet. Dann habe ich dafür gesorgt, dass btoa-atob als Abhängigkeit in meiner package.json-Datei hinzugefügt wird, die sich im Stammverzeichnis befindet.

Dennoch funktioniert es aus irgendeinem Grund immer noch nicht.

console.log(btoa("Hallo Welt!"));

^ sollte "SGVsbG8gV29ybGQh" in der Konsole ausgeben, aber stattdessen erhalte ich den Fehler:

btoa ist nicht definiert.

Habe ich die Installation nicht richtig durchgeführt? Was habe ich übersehen?

917voto

mscdex Punkte 100829

Das Modul 'btoa-atob' exportiert keine programmatische Schnittstelle, sondern stellt nur Befehlszeilen-Dienstprogramme bereit.

Wenn Sie in Base64 konvertieren müssen, könnte dies mit Buffer gemacht werden:

console.log(Buffer.from('Hello World!').toString('base64'));

Rückgängig machen (unter der Annahme, dass der zu decodierende Inhalt eine UTF8-Zeichenfolge ist):

console.log(Buffer.from(b64Encoded, 'base64').toString());

Hinweis: Vor Node v4 verwenden Sie new Buffer anstelle von Buffer.from.

133voto

Iván Alegre Punkte 1838

Die hier geposteten Lösungen funktionieren nicht mit Nicht-ASCII-Zeichen (d.h. wenn Sie base64 zwischen Node.js und einem Browser austauschen möchten). Um es zum Laufen zu bringen, müssen Sie den Eingabetext als 'binär' markieren.

Buffer.from('Hélló wórld!!', 'binary').toString('base64')

Dies gibt Ihnen SOlsbPMgd/NybGQhIQ==. Wenn Sie atob('SOlsbPMgd/NybGQhIQ==') in einem Browser machen, wird es es richtig dekodieren. Es wird es auch in Node.js richtig machen über:

Buffer.from('SOlsbPMgd/NybGQhIQ==', 'base64').toString('binary')

Wenn Sie den "binären Teil" nicht machen, werden die Sonderzeichen falsch dekodiert.

Ich habe es aus der Implementierung des btoa npm-Pakets erhalten:

36voto

PaulMest Punkte 9549

Mein Team ist auf dieses Problem gestoßen, als Node mit React Native und PouchDB verwendet wurde. So haben wir es gelöst...

NPM installiere Buffer:

$ npm install --save buffer

Vergewissern Sie sich, dass Buffer, btoa und atob als globale Variablen geladen sind:

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');
  };
}

20voto

Ali Eslamifard Punkte 565
export const universalBtoa = str => {
  try {
    return btoa(str);
  } catch (err) {
    return Buffer.from(str).toString('base64');
  }
};

export const universalAtob = b64Encoded => {
  try {
    return atob(b64Encoded);
  } catch (err) {
    return Buffer.from(b64Encoded, 'base64').toString();
  }
};

17voto

Jamie Birch Punkte 5229

Ich habe festgestellt, dass obwohl die Abstandshalter aus den oben genannten Antworten funktionierten, sie nicht dem Verhalten der Implementierungen von btoa() und atob() für Desktop-Browser entsprachen:

const btoa = function(str){ return Buffer.from(str).toString('base64'); }
// gibt "4pyT" zurück, aber in Desktop-Chrome würde es einen Fehler auslösen.
btoa('');
// gibt "fsO1w6bCvA==", aber in Desktop-Chrome würde es "fvXmvA==" zurückgeben
btoa(String.fromCharCode.apply(null, new Uint8Array([0x7e, 0xf5, 0xe6, 0xbc])));

Es stellt sich heraus, dass Buffer-Instanzen standardmäßig in UTF-8 kodierten Zeichenfolgen repräsentieren/interpretieren. Im Gegensatz dazu können Sie in Desktop-Chrome nicht einmal eine Zeichenfolge eingeben, die Zeichen außerhalb des lateinischen Bereichs enthält, in btoa(), da es eine Ausnahme auslösen wird: Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

Daher müssen Sie den Codierungstyp explizit auf latin1 setzen, damit Ihr Node.js-Abstandshalter mit dem Codierungstyp von Desktop-Chrome übereinstimmt:

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(''); // gibt "Ew==" zurück (es wäre besser, wenn es einen Fehler auslösen würde, da dies nicht dekodierbar ist)
atobLatin1(btoa('')); // gibt "\u0019" zurück (END OF MEDIUM)

btoaUTF8(''); // gibt "4pyT" zurück
atobUTF8(btoa('')); // gibt ""

// gibt "fvXmvA==" zurück, genau wie in Desktop-Chrome
btoaLatin1(String.fromCharCode.apply(null, new Uint8Array([0x7e, 0xf5, 0xe6, 0xbc])));
// gibt "fsO1w6bCvA==" zurück
btoaUTF8(String.fromCharCode.apply(null, new Uint8Array([0x7e, 0xf5, 0xe6, 0xbc])));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X