我需要一种高效的(即本地实现)方式将ArrayBuffer
转换为Base64字符串,该字符串需要在多部分post中使用。
我需要一种高效的(即本地实现)方式将ArrayBuffer
转换为Base64字符串,该字符串需要在多部分post中使用。
function _arrayBufferToBase64( buffer ) {
var binary = '';
var bytes = new Uint8Array( buffer );
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] );
}
return window.btoa( binary );
}
但是,非本地实现更快,例如:https://gist.github.com/958841 请参见http://jsperf.com/encoding-xhr-image-data/6
更新的基准测试:https://jsben.ch/wnaZC
join()
函数连接它们的速度要快得多(但在Chrome上要慢得多):http://jsperf.com/tobase64-implementations - JLRishetoString('base64')
方法。 - João Eduardo这对我来说很好用:
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
在ES6中,语法略微简化:
const base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
正如评论所指出的那样,当ArrayBuffer
很大时,此方法可能会导致某些浏览器运行时错误。无论如何,确切的大小限制在任何情况下均取决于实现。
btoa([].reduce.call(new Uint8Array(bufferArray),function(p,c){return p+String.fromCharCode(c)},''))
- laggingreflexbtoa
对于代码范围在 0-255 的字符是安全的,因为这里的情况如此(考虑 Uint8Array
中的 8)。 - GOTO 0...
比使用apply
要慢得多。 - JP Sugarbroad对于那些喜欢简短的人,这里有另一个使用Array.reduce
的示例,它不会导致堆栈溢出:
var base64 = btoa(
new Uint8Array(arrayBuffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
<字节数量>
个新字符串。 - Neonitbtoa(new Uint8Array(arraybuffer).reduce((data,byte)=>(data.push(String.fromCharCode(byte)),data),[]).join(''))
怎么样? - Roy Tinkerbtoa(Array.from(new Uint8Array(arraybuffer)).map(b => String.fromCharCode(b)).join(''))
。 - e741af0d41bc74bf854041f1fbdbf还有一种使用Blob和FileReader的异步方式。
我没有测试性能,但这是一种不同的思考方式。
function arrayBufferToBase64( buffer, callback ) {
var blob = new Blob([buffer],{type:'application/octet-binary'});
var reader = new FileReader();
reader.onload = function(evt){
var dataurl = evt.target.result;
callback(dataurl.substr(dataurl.indexOf(',')+1));
};
reader.readAsDataURL(blob);
}
//example:
var buf = new Uint8Array([11,22,33]);
arrayBufferToBase64(buf, console.log.bind(console)); //"CxYh"
dataurl.split(',',2)[1]
替代dataurl.substr(dataurl.indexOf(',')+1)
。 - Carter MedlinreadAsDataURL
理论上可能会返回一个百分号编码的dataURI(而且在jsdom中似乎确实是这种情况)。 - T Ssplit
比 substring
更好呢? - T S// This step is only necessary if you don't already have a Buffer Object
const buffer = Buffer.from(yourArrayBuffer);
const base64String = buffer.toString('base64');
Buffer
类也将在浏览器环境中提供。Javascript
。因此,我更新了我的答案,使其更加简洁。我认为这是一个重要的答案,因为当时我也在搜索如何解决这个问题,但找不到最好的答案。 - João Eduardo这个例子使用内置的 FileReader readDataURL() 来进行转换为 base64 编码。数据 URL 的结构是 data:[<mediatype>][;base64],<data>
,因此我们在逗号处拆分该 URL 并仅返回 base64 编码的字符。
const blob = new Blob([array]);
const reader = new FileReader();
reader.onload = (event) => {
const dataUrl = event.target.result;
const [_, base64] = dataUrl.split(',');
// do something with base64
};
reader.readAsDataURL(blob);
或者作为一个Promise化的实用工具:
async function encode(array) {
return new Promise((resolve) => {
const blob = new Blob([array]);
const reader = new FileReader();
reader.onload = (event) => {
const dataUrl = event.target.result;
const [_, base64] = dataUrl.split(',');
resolve(base64);
};
reader.readAsDataURL(blob);
});
}
const encoded = await encode(typedArray);
我用过这个,对我有用。
function arrayBufferToBase64( buffer ) {
var binary = '';
var bytes = new Uint8Array( buffer );
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] );
}
return window.btoa( binary );
}
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;
}
我建议不要使用原生的btoa
策略——因为它们无法正确编码所有的ArrayBuffer
...
由于DOM字符串是16位编码的字符串,在大多数浏览器中,在Unicode字符串上调用window.btoa将导致字符超出8位ASCII编码字符范围而引发异常。
虽然我从未遇到过这个确切的错误,但我发现许多我尝试编码的ArrayBuffer
都没有正确编码。
我建议使用MDN或者gist。
下面是两个简单的函数,用于将Uint8Array转换为Base64字符串,以及将其再次转回Uint8Array。
arrayToBase64String(a) {
return btoa(String.fromCharCode(...a));
}
base64StringToArray(s) {
let asciiString = atob(s);
return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}
function
关键字,它应该可以在现代浏览器中正常工作。 - Yeti如果您可以添加一个库,可以使用base64-arraybuffer:
yarn add base64-arraybuffer
然后:
encode(buffer)
- 将ArrayBuffer编码为base64字符串decode(str)
- 将base64字符串解码为ArrayBuffer
FormData
和一个Blob
,将Blob附加到FormData中,以二进制形式发送数据,而不是使用base64编码。 - undefined