Node.js - "未定义btoa"错误

Joe*_*oey 184 node.js

在我的node.js应用程序中,我做了一个,npm install btoa-atob以便我可以使用btoa()和atob()函数,这些函数在客户端javascript中是原生的,但由于某种原因未包含在节点中.新目录显示在我的node_modules文件夹中,该文件夹本身与app.js一起位于root目录中.然后我确保在我的package.json文件中添加btoa-atob作为依赖项,该文件位于root中.

但是,由于某种原因,它仍然无法正常工作.

console.log(btoa("Hello World!"));
Run Code Online (Sandbox Code Playgroud)

^应该输出"SGVsbG8gV29ybGQh"到控制台,但我得到错误"btoa不是defiend".

我没有正确安装吗?我忽略了什么?

msc*_*dex 436

'btoa-atob'模块不会导出编程接口,它只提供命令行实用程序.

如果你需要转换为Base64,你可以使用Buffer来实现:

console.log(Buffer.from('Hello World!').toString('base64'));
Run Code Online (Sandbox Code Playgroud)

反向(假设您正在解码的内容是utf8字符串):

console.log(Buffer.from(b64Encoded, 'base64').toString());
Run Code Online (Sandbox Code Playgroud)

注意:在Node v4之前,请使用new Buffer而不是Buffer.from.


Ivá*_*gre 37

此处发布的解决方案不适用于非ascii字符(即,如果您计划在Node.js和浏览器之间交换base64).为了使其工作,您必须将输入文本标记为"二进制".

Buffer.from('Hélló wórld!!', 'binary').toString('base64')
Run Code Online (Sandbox Code Playgroud)

这给了你SOlsbPMgd/NybGQhIQ==.如果您atob('SOlsbPMgd/NybGQhIQ==')在浏览器中制作它将以正确的方式解码它.它也将通过以下方式在Node.js中正确执行:

Buffer.from('SOlsbPMgd/NybGQhIQ==', 'base64').toString('binary')
Run Code Online (Sandbox Code Playgroud)

如果你不做"二进制部分",你将错误地解码特殊字符.

从btoa npm包的实现中得到了它:

  • @TotalAMD 它无法将 Base64 从 Node.js 交换到浏览器,反之亦然 (2认同)
  • 您正在比较base64中的编码和在同一平台上对其进行解码。Chrome到Chrome和Node到Node。如果您在没有二进制文件的节点10中对它进行编码,它将给出“ SMOpbGzDsyB3w7NybGQhIQ ==”。如果您在浏览器中对其进行解码,它将为您提供“HÃllll³wórld!!”。该二进制文件非常适合确保跨平台兼容性。 (2认同)

Pau*_*est 19

在使用带有React Native和PouchDB的Node时,我的团队遇到了这个问题.以下是我们如何解决它......

NPM安装缓冲区:

$ npm install --save buffer
Run Code Online (Sandbox Code Playgroud)

确保Buffer,, btoaatob作为全局变量加载:

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');
  };
}
Run Code Online (Sandbox Code Playgroud)

  • @RodrigoDeAlmeidaSiqueira,您可以使用 Buffer.from() 来修复警告:) (3认同)
  • 您的代码中的命令new Buffer()在较新版本的节点中给出以下错误:[DEP0005] DeprecationWarning:由于安全性和可用性问题,不建议使用Buffer()。请改用Buffer.alloc(),Buffer.allocUnsafe()或Buffer.from()方法。 (2认同)

Jam*_*rch 8

我发现虽然上面的答案中的垫片工作,但它们与桌面浏览器的实现btoa()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])));
Run Code Online (Sandbox Code Playgroud)

事实证明,Buffer实例表示/解释默认情况下以UTF-8编码的字符串.相比之下,在桌面Chrome中,您甚至无法输入包含latin1范围之外的字符的字符串btoa(),因为它会引发异常:Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

因此,你需要将明确设置编码类型latin1为了你的Node.js垫片,以配合桌面版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])));
Run Code Online (Sandbox Code Playgroud)


Ale*_*der 8

我有一个在服务器和客户端之间共享的代码,我需要在其中实现 btoa。我尝试做类似的事情:

const btoaImplementation =  btoa || (str => Buffer.from(str).toString('base64'));
Run Code Online (Sandbox Code Playgroud)

但服务器会粉碎:

ReferenceError: btoa 未定义

whileBuffer未在客户端上定义。

我无法检查 window.btoa(这是一个共享代码,还记得吗?)

所以我最终得到了这个实现:

const btoaImplementation = str => {
    try {
        return btoa(str);
    } catch(err) {
        return Buffer.from(str).toString('base64')
    }
};
Run Code Online (Sandbox Code Playgroud)


Sak*_*ket 8

我能够使用btoa下面的 npm 包将二进制数据用于基 64 字符串转换: https: //www.npmjs.com/package/btoa

正如他们的文档中所述,我在 Node JS 应用程序中执行了以下步骤:

  1. 安装=>npm install --save btoa
  2. 在顶部声明 =>const btoa = require('btoa');
  3. 使用=>const b64 = btoa("stringToEncode");


Rut*_*rde 8

任何想要解码的人:

let decoded = Buffer.from(<encoded string>, 'base64').toString()

因为我来这里寻找解码,最终从这里的答案中弄清楚了。

  • @JCutting8 当然是同步的:) (2认同)

ali*_*ard 7

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();
  }
};
Run Code Online (Sandbox Code Playgroud)


Luk*_*lor 7

这是一个简洁的 Base64 编码通用解决方案:

const nodeBtoa = (b) => Buffer.from(b).toString('base64');
export const base64encode = typeof btoa !== 'undefined' ? btoa : nodeBtoa;
Run Code Online (Sandbox Code Playgroud)


Shr*_*mpy 5

Atom 编辑器中的“script”插件也有同样的问题,它是旧版本的节点,没有 btoa(),也没有 atob(),也不支持 Buffer 数据类型。下面的代码可以解决这个问题:

var Base64 = new function() {
  var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
  this.encode = function(input) {
    var output = "";
    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
    var i = 0;
    input = Base64._utf8_encode(input);
    while (i < input.length) {
      chr1 = input.charCodeAt(i++);
      chr2 = input.charCodeAt(i++);
      chr3 = input.charCodeAt(i++);
      enc1 = chr1 >> 2;
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
      enc4 = chr3 & 63;
      if (isNaN(chr2)) {
        enc3 = enc4 = 64;
      } else if (isNaN(chr3)) {
        enc4 = 64;
      }
      output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);
    }
    return output;
  }

  this.decode = function(input) {
    var output = "";
    var chr1, chr2, chr3;
    var enc1, enc2, enc3, enc4;
    var i = 0;
    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
    while (i < input.length) {
      enc1 = keyStr.indexOf(input.charAt(i++));
      enc2 = keyStr.indexOf(input.charAt(i++));
      enc3 = keyStr.indexOf(input.charAt(i++));
      enc4 = keyStr.indexOf(input.charAt(i++));
      chr1 = (enc1 << 2) | (enc2 >> 4);
      chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
      chr3 = ((enc3 & 3) << 6) | enc4;
      output = output + String.fromCharCode(chr1);
      if (enc3 != 64) {
        output = output + String.fromCharCode(chr2);
      }
      if (enc4 != 64) {
        output = output + String.fromCharCode(chr3);
      }
    }
    output = Base64._utf8_decode(output);
    return output;
  }

  this._utf8_encode = function(string) {
    string = string.replace(/\r\n/g, "\n");
    var utftext = "";
    for (var n = 0; n < string.length; n++) {
      var c = string.charCodeAt(n);
      if (c < 128) {
        utftext += String.fromCharCode(c);
      } else if ((c > 127) && (c < 2048)) {
        utftext += String.fromCharCode((c >> 6) | 192);
        utftext += String.fromCharCode((c & 63) | 128);
      } else {
        utftext += String.fromCharCode((c >> 12) | 224);
        utftext += String.fromCharCode(((c >> 6) & 63) | 128);
        utftext += String.fromCharCode((c & 63) | 128);
      }
    }
    return utftext;
  }

  this._utf8_decode = function(utftext) {
    var string = "";
    var i = 0;
    var c = 0,
      c1 = 0,
      c2 = 0,
      c3 = 0;
    while (i < utftext.length) {
      c = utftext.charCodeAt(i);
      if (c < 128) {
        string += String.fromCharCode(c);
        i++;
      } else if ((c > 191) && (c < 224)) {
        c2 = utftext.charCodeAt(i + 1);
        string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
        i += 2;
      } else {
        c2 = utftext.charCodeAt(i + 1);
        c3 = utftext.charCodeAt(i + 2);
        string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
        i += 3;
      }
    }
    return string;
  }
}()

var btoa = Base64.encode;
var atob = Base64.decode;

console.log("btoa('A') = " + btoa('A'));
console.log("btoa('QQ==') = " + atob('QQ=='));
console.log("btoa('B') = " + btoa('B'));
console.log("btoa('Qg==') = " + atob('Qg=='));
Run Code Online (Sandbox Code Playgroud)