web-dev-qa-db-fra.com

Convertir une chaîne en base64 en ArrayBuffer

J'ai besoin de convertir une chaîne d'encodage en base64 en un ArrayBuffer . Les chaînes en base64 sont une entrée utilisateur, elles seront copiées et collées à partir d'un email, afin qu'elles ne soient pas présentes lorsque la page est chargée . faire cela en javascript sans faire un appel ajax au serveur si possible.

J'ai trouvé ces liens intéressants, mais ils ne m'ont pas aidé:

ArrayBuffer en chaîne encodée en base64

il s’agit de la conversion inverse, de ArrayBuffer à base64, et non l’inverse

http://jsperf.com/json-vs-base64/2

cela a l'air bien mais je n'arrive pas à comprendre comment utiliser le code.

Existe-t-il un moyen facile (peut-être natif) de procéder à la conversion? Merci

60
Tony

Essaye ça:

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;
}
96
Goran.it

La réponse de Goran.it ne fonctionne pas à cause d'un problème unicode dans javascript - https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding

J'ai fini par utiliser la fonction donnée sur le blog de Daniel Guerrero: http://blog.danguer.com/2011/10/24/base64-binary-decoding-in-javascript/

La fonction est répertoriée sur le lien github: https://github.com/danguer/blog-examples/blob/master/js/base64-binary.js

Utilisez ces lignes 

var uintArray = Base64Binary.decode(base64_string);  
var byteArray = Base64Binary.decodeArrayBuffer(base64_string); 
21
Yaan

Utiliser TypedArray.from :

Uint8Array.from(atob(base64_string), c => c.charCodeAt(0))

Performances à comparer avec la version boucle for de la réponse Goran.it.

21
ofavre

Je viens de trouver base64-arraybuffer, un petit paquet npm avec une utilisation incroyablement élevée, 5 millions de téléchargements le mois dernier (2017-08).

https://www.npmjs.com/package/base64-arraybuffer

Pour ceux qui recherchent une solution standard optimale, c'est peut-être ça.

10
alias65536

Javascript est un bel environnement de développement, il semble donc étrange de ne pas fournir de solution à ce petit problème. Les solutions proposées ailleurs sur cette page sont potentiellement lentes. Voici ma solution. Il utilise la fonctionnalité intégrée qui décode les URL de données image64 et son 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();

La demande d'envoi échoue si la chaîne en base 65 est mal formée.

Le type mime (application/octet) est probablement inutile.

Testé en chrome. Devrait fonctionner dans d'autres navigateurs.

4
dinosaurclover

Async solution, c'est mieux quand les données sont volumineuses:

// 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);
}
0
张浩然