回答:
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を 参照
join()
し、最後にそれらをingすることは、Firefox、IE、およびSafariではかなり高速です(ただし、Chromeではかなり遅くなります):jsperf.com/tobase64-implementations
Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
これは私にとってはうまくいきます:
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
ES6では、構文は少し単純です。
let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
コメントで指摘されているように、このメソッドArrayBuffer
が大きい場合、一部のブラウザでランタイムエラーが発生する可能性があります。正確なサイズ制限は、どのような場合でも実装に依存します。
btoa([].reduce.call(new Uint8Array(bufferArray),function(p,c){return p+String.fromCharCode(c)},''))
btoa
は、コード範囲0-255の文字に対して安全です。これが当てはまるためです(の8について考えてくださいUint8Array
)。
短いものが好きな人のために、Array.reduce
スタックオーバーフローを引き起こさない他の使用方法があります:
var base64 = btoa(
new Uint8Array(arrayBuffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
<amount of Bytes in the buffer>
新しい文字列を作成しています。
btoa(new Uint8Array(arraybuffer).reduce((data,byte)=>(data.push(String.fromCharCode(byte)),data),[]).join(''))
ですか?
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)
。
readAsDataURL
、理論的にはパーセントでエンコードされたdataURIを返す可能性があります(実際にはjsdomの場合にそうです)
split
より良いですsubstring
か?
私はこれを使用して私のために働いています。
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
です…
DOMStringsは16ビットでエンコードされた文字列であるため、ほとんどのブラウザでは、文字が8ビットのASCIIエンコードされた文字の範囲を超えると、Unicode文字列でwindow.btoaを呼び出すと、文字の範囲外の例外が発生します。
この正確なエラーに遭遇したことはありませんが、ArrayBuffer
エンコードしようとしたの多くが正しくエンコードされていないことがわかりました。
MDN推奨または要旨を使用します。
btoa
Stringでは機能しませんが、OPはを求めていArrayBuffer
ます。
var blob = new Blob([arrayBuffer])
var reader = new FileReader();
reader.onload = function(event){
var base64 = event.target.result
};
reader.readAsDataURL(blob);
以下は、Uint8ArrayをBase64文字列に変換して再度戻すための2つの単純な関数です。
arrayToBase64String(a) {
return btoa(String.fromCharCode(...a));
}
base64StringToArray(s) {
let asciiString = atob(s);
return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}
function
キーワードを追加すると、最新のブラウザで機能するはずです。
ArrayBuffer
を使用して、から通常の配列を導出できますArray.prototype.slice
。などの関数を使用して、Array.prototype.map
バイトを文字に変換し、join
それらをまとめて文字列を形成します。
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
}
この方法では、文字列の連結が実行されていないため、より高速です。
OPはRunning Enviromentを指定していませんが、Node.JSを使用している場合、そのようなことを行う非常に簡単な方法があります。
公式のNode.JSドキュメントhttps://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodingsで Accordig
// This step is only necessary if you don't already have a Buffer Object
const buffer = Buffer.from(yourArrayBuffer);
const base64String = buffer.toString('base64');
また、たとえばAngularで実行している場合は、ブラウザクラスでもバッファクラスを使用できます。
Javascript
。タグを付けただけです。だから私はそれをより簡潔にするために私の答えを更新しました。私はこれを行う方法を探していて、問題に対する最良の答えを得ることができなかったので、これは重要な答えだと思います。
私の側では、Chromeナビゲーターを使用して、ArrayViewを読み取るためにDataView()を使用する必要がありました
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;}
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を使用して文字列からアーカイブを解凍する場合に適しています