ArrayBuffer to base64 encoded string
我需要一种有效的(本机读)方法来将arrayBuffer转换为base64字符串,该字符串需要在多部分日志中使用。
1 2 3 4 5 6 7 8 9 | 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://jspef.com/encoding-xhr-image-data/6
这对我来说很好:
1 | var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer))); |
在ES6中,语法稍微简单一点:
1 | let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer))); |
正如注释中指出的,当arrayBuffer很大时,此方法可能会在某些浏览器中导致运行时错误。具体的大小限制在任何情况下都取决于实现。
还有另一种异步方式使用blob和filereader。
我没有测试性能。但这是一种不同的思维方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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" |
对于喜欢简短的人,这里还有一个使用
1 2 3 4 | var base64 = btoa( new Uint8Array(arrayBuffer) .reduce((data, byte) => data + String.fromCharCode(byte), '') ); |
我的建议是不要使用本地的
重写doms atob()和btoa()。
Since DOMStrings are 16-bit-encoded strings, in most browsers calling window.btoa on a Unicode string will cause a Character Out Of Range exception if a character exceeds the range of a 8-bit ASCII-encoded character.
虽然我从未遇到过这种确切的错误,但我发现我尝试编码的许多
我要么使用MDN推荐,要么使用GIST。
- 网址:https://github.com/beatgammit/base64-js
- https://gist.github.com/jonleighton/958841
我用这个为我工作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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; } |
下面是将uint8array转换为base64字符串并再次返回的两个简单函数
1 2 3 4 5 6 7 8 | arrayToBase64String(a) { return btoa(String.fromCharCode(...a)); } base64StringToArray(s) { let asciiString = atob(s); return new Uint8Array([...asciiString].map(char => char.charCodeAt(0))); } |
您可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 | function arrayBufferToBase64(ab){ var dView = new Uint8Array(ab); //Get a byte view var arr = Array.prototype.slice.call(dView); //Create a normal array var arr1 = arr.map(function(item){ return String.fromCharCode(item); //Convert }); return window.btoa(arr1.join('')); //Form a string } |
此方法更快,因为其中没有运行字符串连接。
在我这边,使用chrome navigator,我必须使用dataview()来读取arraybuffer
1 2 3 4 5 6 7 8 9 10 11 | function _arrayBufferToBase64( tabU8A ) { var binary = ''; let lecteur_de_donnees = new DataView(tabU8A); var len = lecteur_de_donnees.byteLength; var chaine = ''; var pos1; for (var i = 0; i < len; i++) { binary += String.fromCharCode( lecteur_de_donnees.getUint8( i ) ); } chaine = window.btoa( binary ) return chaine;} |
1 2 3 4 5 6 7 8 9 10 | function _arrayBufferToBase64(uarr) { var strings = [], chunksize = 0xffff; var len = uarr.length; for (var i = 0; i * chunksize < len; i++){ strings.push(String.fromCharCode.apply(null, uarr.subarray(i * chunksize, (i + 1) * chunksize))); } return strings.join(""); } |
如果您使用jszip从字符串中解包归档文件,这会更好。