268

ArrayBufferマルチパート投稿で使用する必要があるbase64文字列に変換する効率的な(ネイティブを読み取る)方法が必要です。

4

14 に答える 14

284
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

于 2012-02-27T01:29:02.580 に答える
143

これは私にとってはうまくいきます:

var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));

ES6 では、構文はもう少し単純です。

const base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));

コメントで指摘されているように、このメソッドは、ArrayBufferサイズが大きい場合、一部のブラウザーで実行時エラーを引き起こす可能性があります。正確なサイズ制限は、いずれの場合も実装に依存します。

于 2012-07-19T14:02:01.130 に答える
42

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"
于 2016-07-10T10:52:09.223 に答える
17

私はこれを使用し、私のために働きます。

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;
}
于 2016-08-09T18:38:48.180 に答える
14

これに対する私の推奨事項は、ネイティブbtoa戦略を使用しないことです—それらはすべてのを正しくエンコードしないためArrayBufferです…</p>

DOM の atob() と btoa() を書き直す

DOMStrings は 16 ビットでエンコードされた文字列であるため、ほとんどのブラウザーで Unicode 文字列に対して window.btoa を呼び出すと、文字が 8 ビット ASCII でエンコードされた文字の範囲を超えている場合、Character Out Of Range 例外が発生します。

この正確なエラーに遭遇したことはありませんが、ArrayBufferエンコードしようとした の多くが正しくエンコードされていないことがわかりました。

MDN の推奨事項または要旨を使用します。

于 2015-07-25T00:15:18.753 に答える
0

ArrayBufferを使用して、 から通常の配列を派生させることができますArray.prototype.sliceArray.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

}

この方法は、文字列連結が実行されていないため高速です。

于 2016-12-08T05:02:23.473 に答える
-4

私の側では、Chrome ナビゲーターを使用して、DataView() を使用して arrayBuffer を読み取る必要がありました

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;}
于 2019-02-06T21:17:08.927 に答える
-6
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を使用する場合、これはより良いです

于 2015-07-23T17:11:40.217 に答える