在我的node.js应用程序中,我做了一个npm install btoa-atob
,这样我就可以使用btoa()和atob()函数,这些函数在客户端javascript中是原生的,但由于某种原因未包含在节点中。新目录显示在我的node_modules文件夹中,该文件夹本身与app.js一起位于root目录中。然后我确保在我的package.json文件中添加btoa-atob作为依赖项。该文件位于root。
然而,由于某种原因,它仍然无效。
console.log(btoa("Hello World!"));
^应该输出“SGVsbG8gV29ybGQh”到控制台,但我得到错误“btoa不是defiend。”
我没有正确安装吗?我忽略了什么?
答案 0 :(得分:353)
'btoa-atob'模块不会导出编程接口,它只提供命令行实用程序。
如果您需要转换为Base64,可以使用Buffer:
console.log(Buffer.from('Hello World!').toString('base64'));
反向(假设您正在解码的内容是utf8字符串):
console.log(Buffer.from(b64Encoded, 'base64').toString());
注意:在Node v4之前,请使用new Buffer
而不是Buffer.from
。
答案 1 :(得分:26)
此处发布的解决方案不适用于非ascii字符(即,如果您计划在Node.js和浏览器之间交换base64)。为了使其工作,您必须将输入文本标记为“二进制”。
tmp <- system('python C:/coa/script_tool/pathgetter.py', intern=TRUE)
这会给你Buffer.from('Hélló wórld!!', 'binary').toString('base64')
。如果您在浏览器中生成SOlsbPMgd/NybGQhIQ==
,它将以正确的方式对其进行解码。它也将通过以下方式在Node.js中正确执行:
atob('SOlsbPMgd/NybGQhIQ==')
如果你不做“二进制部分”,你将错误地解码特殊字符。
答案 2 :(得分:16)
使用带有React Native和PouchDB的Node时,我的团队遇到了这个问题。以下是我们如何解决它......
NPM安装缓冲区:
$ npm install --save buffer
确保Buffer
,btoa
和atob
作为全局变量加载:
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');
};
}
答案 3 :(得分:6)
我发现尽管上述答案中的垫片有效,但它们与桌面浏览器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])));
事实证明,Buffer
个实例代表/解释以UTF-8 by default编码的字符串。相比之下,在桌面Chrome中,您甚至无法将包含latin1范围之外的字符的字符串输入btoa()
,因为它会引发异常:Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
因此,您需要明确将encoding type设置为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])));
答案 4 :(得分:4)
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();
}
};
答案 5 :(得分:3)
这是针对base64编码的简洁通用解决方案:
const nodeBtoa = (b) => Buffer.from(b).toString('base64');
export const base64encode = typeof btoa !== 'undefined' ? btoa : nodeBtoa;
答案 6 :(得分:1)
我理解这是节点应用程序的讨论点,但为了通用JavaScript应用程序在节点服务器上运行,这就是我到达这篇文章的方式,我一直在研究这个对于我一直在构建的通用/同构反应应用程序,包abab
为我工作。事实上,这是我能找到的唯一解决方案,而不是使用也提到的Buffer方法(我有打字稿问题)。
(此程序包由jsdom
使用,而window
程序包又使用此程序包。)
回到我的观点;基于此,也许如果这个功能已经像你提到的那样编写为npm包,并且拥有基于W3规范的自己的算法,你可以安装和使用abab
包而不是编写你自己的函数根据编码可能准确,也可能不准确。
--- 修改强> ---
我今天开始使用包abab
进行编码(不确定为什么现在开始发生)的奇怪问题。它似乎在大多数时间正确编码,但有时在前端它编码不正确。花了很长时间尝试调试,但按照建议切换到包base-64
,它立即起作用。绝对似乎是abab
的base64算法。
答案 7 :(得分:0)
我有服务器和客户端之间共享的代码,我需要在其中实现btoa。 我尝试做类似的事情:
https://dotnet.microsoft.com/learn/aspnet/microservice-tutorial/create
但是服务器会崩溃:
ReferenceError:未定义btoa
const btoaImplementation = btoa || (str => Buffer.from(str).toString('base64'));
尚未在客户端上定义。
我无法检查window.btoa(这是共享的代码,还记得吗?)
所以我最终完成了该实现:
Buffer
答案 8 :(得分:0)
也许您不再需要它,但是如果有人使用节点需要它: https://www.npmjs.com/package/btoa
答案 9 :(得分:0)
Atom编辑器中的'script'插件存在相同的问题,它是node的旧版本,不具有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=='));
答案 10 :(得分:0)
我能够使用 btoa
使用以下 npm 包将二进制数据转换为 base 64 字符串:
https://www.npmjs.com/package/btoa
如他们的文档中所述,我在 node JS 应用程序中执行了以下步骤:
npm install --save btoa
const btoa = require('btoa');
const b64 = btoa("stringToEncode");