我需要将base64编码字符串转换为ArrayBuffer。 base64字符串是用户输入,它们将从电子邮件中复制和粘贴,因此在加载页面时它们不存在。 我希望在javascript中执行此操作,如果可能的话,不要对服务器进行ajax调用。
我发现这些链接很有趣,但他们没有帮助我:
ArrayBuffer to base64 encoded string
这是相反的转换,从ArrayBuffer到base64,而不是相反的转换
http://jsperf.com/json-vs-base64/2
这看起来不错,但我无法弄清楚如何使用代码。
是否有简单的(可能是原生的)方式进行转换?感谢
答案 0 :(得分:105)
试试这个:
function _base64ToArrayBuffer(base64) {
var binary_string = window.atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array( len );
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
}
答案 1 :(得分:25)
Uint8Array.from(atob(base64_string), c => c.charCodeAt(0))
将性能与Goran.it答案的for循环版本进行比较。
答案 2 :(得分:23)
由于javascript中的unicode问题,Goran.it的答案不起作用 - https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding。
我最终使用了Daniel Guerrero的博客http://blog.danguer.com/2011/10/24/base64-binary-decoding-in-javascript/
功能列在github链接上:https://github.com/danguer/blog-examples/blob/master/js/base64-binary.js
使用这些行
var uintArray = Base64Binary.decode(base64_string);
var byteArray = Base64Binary.decodeArrayBuffer(base64_string);
答案 3 :(得分:11)
刚刚找到了base64-arraybuffer,一个小的npm软件包,使用率非常高,上个月(2017-08)下载量为500万。
https://www.npmjs.com/package/base64-arraybuffer
对于寻找最佳标准解决方案的人来说,可能就是这样。
答案 4 :(得分:8)
对于Node.js用户:
const myBuffer = Buffer.from(someBase64String, 'base64');
myBuffer的类型为Buffer,它是Uint8Array的子类。不幸的是,Uint8Array不是OP所要求的ArrayBuffer。但是,当操作ArrayBuffer时,我几乎总是用Uint8Array或类似的东西包装它,因此它应该接近所要求的。
答案 5 :(得分:4)
Javascript是一个很好的开发环境,所以看起来很奇怪,因为它没有为这个小问题提供解决方案。本页其他地方提供的解决方案可能很慢。这是我的解决方案。它采用内置功能解码base64图像和声音数据网址。
var req = new XMLHttpRequest;
req.open('GET', "data:application/octet;base64," + base64Data);
req.responseType = 'arraybuffer';
req.onload = function fileLoaded(e)
{
var byteArray = new Int8Array(e.target.response);
// var shortArray = new Int16Array(e.target.response);
// var unsignedShortArray = new Int16Array(e.target.response);
// etc.
}
req.send();
如果基础65字符串格式错误,发送请求将失败。
可能不需要mime类型(应用程序/八位字节)。
在chrome中测试过。应该可以在其他浏览器中使用。
答案 6 :(得分:2)
异步解决方案,当数据量大时最好:
// base64 to buffer
function base64ToBufferAsync(base64) {
var dataUrl = "data:application/octet-binary;base64," + base64;
fetch(dataUrl)
.then(res => res.arrayBuffer())
.then(buffer => {
console.log("base64 to buffer: " + new Uint8Array(buffer));
})
}
// buffer to base64
function bufferToBase64Async( buffer ) {
var blob = new Blob([buffer], {type:'application/octet-binary'});
console.log("buffer to blob:" + blob)
var fileReader = new FileReader();
fileReader.onload = function() {
var dataUrl = fileReader.result;
console.log("blob to dataUrl: " + dataUrl);
var base64 = dataUrl.substr(dataUrl.indexOf(',')+1)
console.log("dataUrl to base64: " + base64);
};
fileReader.readAsDataURL(blob);
}
答案 7 :(得分:2)
我写了下面的函数,该函数直接转换base64(在中间步骤不转换为字符串)。想法
=
字符结尾,则从输出数组中删除一个/两个数字以下解决方案允许处理大型输入base64字符串。将字节转换为不带btoa的base64的类似功能为HERE
function base64ToBytesArr(str) {
const abc = [..."ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"]; // base64 alphabet
let result = [];
for(let i=0; i<str.length/4; i++) {
let chunk = [...str.slice(4*i,4*i+4)]
let bin = chunk.map(x=> abc.indexOf(x).toString(2).padStart(6,0)).join('');
let bytes = bin.match(/.{1,8}/g).map(x=> +('0b'+x));
result.push(...bytes.slice(0,3 - (str[4*i+2]=="=") - (str[4*i+3]=="=")));
}
return result;
}
// --------
// TEST
// --------
let test = "Alice's Adventure in Wonderland.";
console.log('test string:', test.length, test);
let b64_btoa = btoa(test);
console.log('encoded string:', b64_btoa);
let decodedBytes = base64ToBytesArr(b64_btoa); // decode base64 to array of bytes
console.log('decoded bytes:', JSON.stringify(decodedBytes));
let decodedTest = decodedBytes.map(b => String.fromCharCode(b) ).join``;
console.log('Uint8Array', JSON.stringify(new Uint8Array(decodedBytes)));
console.log('decoded string:', decodedTest.length, decodedTest);
答案 8 :(得分:0)
我强烈建议您使用正确实现base64规范的npm软件包。
我认识的最好的人是rfc4648
问题是btoa和atob使用二进制字符串而不是Uint8Array,并且尝试与之进行转换很麻烦。为此,在npm中还有很多坏包。我花了很多时间才找到那个人。
该特定程序包的创建者做了一件简单的事情:他们采用了Base64的规范(顺便说是here),并从头到尾正确地实现了它。 (包括规范中其他有用的其他格式,例如Base64-url,Base32等)。这似乎并不多,但显然对许多其他库而言,要求太多了。
是的,我知道我在做些义教活动,但是如果您也想避免浪费时间,也可以使用rfc4648。
答案 9 :(得分:-1)
const str = "this is base64 string"
const encoded = new TextEncoder().encode(str) // is Uint8Array
const buf = encoded.buffer // is ArrayBuffer
实际上,您可以编码/解码任何字符串,而不仅仅是base64字符串。
请注意,您应该编码base64字符串。此代码不能编码为base64!
MDN:https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder