701 Stimmen

Erstellen eines BLOB aus einem Base64-String in JavaScript

Ich habe Base64-codierte Binärdaten in einem String:

const contentType = 'image/png';
const b64Data = 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';

Ich möchte eine blob: URL erstellen, die diese Daten enthält, und sie dem Benutzer anzeigen:

const blob = new Blob(????, {type: contentType});
const blobUrl = URL.createObjectURL(blob);

window.location = blobUrl;

Ich konnte bisher nicht herausfinden, wie ich den BLOB erstellen kann.

In einigen Fällen kann ich dies vermeiden, indem ich stattdessen eine data: URL verwende:

const dataUrl = `data:${contentType};base64,${b64Data}`;

window.location = dataUrl;

In den meisten Fällen sind die data: URLs jedoch unpraktisch groß.


Wie kann ich einen Base64-String in ein BLOB-Objekt in JavaScript dekodieren?

23voto

Eyup Yusein Punkte 351

Für alle Copy-Paste-Liebhaber da draußen wie mich, hier ist eine fertige Download-Funktion, die in Chrome, Firefox und Edge funktioniert:

window.saveFile = function (bytesBase64, mimeType, fileName) {
var fileUrl = "data:" + mimeType + ";base64," + bytesBase64;
fetch(fileUrl)
    .then(response => response.blob())
    .then(blob => {
        var link = window.document.createElement("a");
        link.href = window.URL.createObjectURL(blob, { type: mimeType });
        link.download = fileName;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    });
}

22voto

Alejandro Reyes Punkte 426

Siehe dieses Beispiel: https://jsfiddle.net/pqhdce2L/

function b64toBlob(b64Data, contentType, sliceSize) {
  contentType = contentType || '';
  sliceSize = sliceSize || 512;

  var byteCharacters = atob(b64Data);
  var byteArrays = [];

  for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    var slice = byteCharacters.slice(offset, offset + sliceSize);

    var byteNumbers = new Array(slice.length);
    for (var i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }

    var byteArray = new Uint8Array(byteNumbers);

    byteArrays.push(byteArray);
  }

  var blob = new Blob(byteArrays, {type: contentType});
  return blob;
}

var contentType = 'image/png';
var b64Data = Ihre Base64-Codierung;

var blob = b64toBlob(b64Data, contentType);
var blobUrl = URL.createObjectURL(blob);

var img = document.createElement('img');
img.src = blobUrl;
document.body.appendChild(img);

18voto

gabriele.genta Punkte 471

Wenn Sie eine Abhängigkeit zu Ihrem Projekt hinzufügen können, gibt es das großartige blob-util npm-Paket, das eine praktische base64StringToBlob-Funktion bietet. Sobald es zu Ihrem package.json hinzugefügt wurde, können Sie es wie folgt verwenden:

import { base64StringToBlob } from 'blob-util';

const contentType = 'image/png';
const b64Data = 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';

const blob = base64StringToBlob(b64Data, contentType);

// Machen Sie, was immer Sie mit Ihrem Blob benötigen...

16voto

Amir Nissim Punkte 3143

Für Bilddaten finde ich es einfacher, canvas.toBlob zu verwenden (asynchron)

function b64toBlob(b64, onsuccess, onerror) {
    var img = new Image();

    img.onerror = onerror;

    img.onload = function onload() {
        var canvas = document.createElement('canvas');
        canvas.width = img.width;
        canvas.height = img.height;

        var ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

        canvas.toBlob(onsuccess);
    };

    img.src = b64;
}

var base64Data = 'data:image/jpg;base64,/9j/4AAQSkZJRgABAQA...';
b64toBlob(base64Data,
    function(blob) {
        var url = window.URL.createObjectURL(blob);
        // do something with url
    }, function(error) {
        // handle error
    });

16voto

Papi Punkte 741

Ich poste eine mehr deklarative Methode zur synchronen Base64-Konvertierung. Während async fetch().blob() sehr ordentlich ist und mir diese Lösung sehr gefällt, funktioniert es nicht auf Internet Explorer 11 (und wahrscheinlich Edge - ich habe diesen nicht getestet), auch mit dem Polyfill nicht - schauen Sie sich meinen Kommentar bei Endless' Beitrag für weitere Details.

const blobPdfFromBase64String = base64String => {
   const byteArray = Uint8Array.from(
     atob(base64String)
       .split('')
       .map(char => char.charCodeAt(0))
   );
  return new Blob([byteArray], { type: 'application/pdf' });
};

Bonus

Wenn Sie es ausdrucken möchten, könnten Sie etwas Ähnliches tun:

const isIE11 = !!(window.navigator && window.navigator.msSaveOrOpenBlob); // Oder wie auch immer Sie es überprüfen möchten
const printPDF = blob => {
   try {
     isIE11
       ? window.navigator.msSaveOrOpenBlob(blob, 'documents.pdf')
       : printJS(URL.createObjectURL(blob)); // http://printjs.crabbly.com/
   } catch (e) {
     throw PDFError;
   }
};

Bonus x 2 - Öffnen einer BLOB-Datei in einem neuen Tab für Internet Explorer 11

Wenn Sie in der Lage sind, eine Vorverarbeitung des Base64-Strings auf dem Server durchzuführen, könnten Sie diesen unter einer bestimmten URL freigeben und den Link in printJS verwenden :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X