我有一个base64编码的二进制数据字符串:

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

我想创建一个包含此数据的blob: URL,并将其显示给用户:

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

window.location = blobUrl;

我一直没能弄清楚如何创建BLOB。

在某些情况下,我可以通过使用data: URL来避免这种情况:

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

window.location = dataUrl;

然而,在大多数情况下,数据:url非常大。


我如何解码一个Base64字符串到一个BLOB对象在JavaScript?


当前回答

请看这个例子: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 = Your Base64 encode; var blob = b64toBlob(b64Data, contentType); var blobUrl = URL.createObjectURL(blob); var img = document.createElement('img'); img.src = blobUrl; document.body.appendChild(img);

其他回答

对于所有浏览器的支持,特别是在Android上,也许你可以添加这个:

try{
    blob = new Blob(byteArrays, {type : contentType});
}
catch(e){
    // TypeError old Google Chrome and Firefox
    window.BlobBuilder = window.BlobBuilder ||
                         window.WebKitBlobBuilder ||
                         window.MozBlobBuilder ||
                         window.MSBlobBuilder;
    if(e.name == 'TypeError' && window.BlobBuilder){
        var bb = new BlobBuilder();
        bb.append(byteArrays);
        blob = bb.getBlob(contentType);
    }
    else if(e.name == "InvalidStateError"){
        // InvalidStateError (tested on FF13 WinXP)
        blob = new Blob(byteArrays, {type : contentType});
    }
    else{
        // We're screwed, blob constructor unsupported entirely
    }
}

这将被证明是一个很短的解决办法。

const byteArray = new Buffer(base64String.replace(/^[\w\d;:\/]+base64\,/g, ''), 'base64');

base64String是包含以64为基数的字符串。

byteArray是你需要的数组。

regex替换是可选的,只是用于处理dataurl字符串中的前缀。

我将发布一种更声明性的同步Base64转换方式。虽然async fetch().blob()非常整洁,我非常喜欢这个解决方案,但它在Internet Explorer 11(可能还有Edge -我还没有测试过这个)上不起作用,即使是在polyfill上-看看我对Endless的帖子的评论,了解更多细节。

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

奖金

如果你想打印它,你可以这样做:

const isIE11 = !!(window.navigator && window.navigator.msSaveOrOpenBlob); // Or however you want to check it
const printPDF = blob => {
   try {
     isIE11
       ? window.navigator.msSaveOrOpenBlob(blob, 'documents.pdf')
       : printJS(URL.createObjectURL(blob)); // http://printjs.crabbly.com/
   } catch (e) {
     throw PDFError;
   }
};

奖金x 2 -打开一个BLOB文件在新选项卡为Internet Explorer 11

如果你能够在服务器上对Base64字符串做一些预处理,你可以在一些URL下公开它,并使用printJS中的链接:)

如果你能忍受在你的项目中添加一个依赖,有一个很棒的blob-util npm包,它提供了一个方便的base64StringToBlob函数。一旦添加到您的包。Json,你可以这样使用它:

import { base64StringToBlob } from 'blob-util';

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

const blob = base64StringToBlob(b64Data, contentType);

// Do whatever you need with your blob...

对于所有像我一样喜欢复制粘贴的人来说,这里有一个可以在Chrome、Firefox和Edge上运行的现成下载功能:

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);
    });
}