Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JavaScript中从Base64字符串创建BLOB_Javascript_Base64 - Fatal编程技术网

在JavaScript中从Base64字符串创建BLOB

在JavaScript中从Base64字符串创建BLOB,javascript,base64,Javascript,Base64,我有一个字符串中的Base64编码二进制数据: const contentType='image/png'; 常数B64数据='IVBORW0KGGOAAAANSUHEUGAAAAAAAFCAYAAACNBYAAAAHELEQVQI12P4//8/W38GIAXDIBKE0DHXGLJNBAO9TXL0Y4OHWAAAABJRU5ERKJGG='; 我想创建一个包含此数据的blob:URL,并将其显示给用户: constblob=newblob(??,{type:contentType});

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

const contentType='image/png';
常数B64数据='IVBORW0KGGOAAAANSUHEUGAAAAAAAFCAYAAACNBYAAAAHELEQVQI12P4//8/W38GIAXDIBKE0DHXGLJNBAO9TXL0Y4OHWAAAABJRU5ERKJGG=';
我想创建一个包含此数据的
blob:
URL,并将其显示给用户:

constblob=newblob(??,{type:contentType});
const blobUrl=URL.createObjectURL(blob);
window.location=blobUrl;
我还没有弄清楚如何创建BLOB

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

constdataurl=`data:${contentType};base64,${b64Data}`;
window.location=dataUrl;
但是,在大多数情况下,
数据:
URL的大小令人望而却步



如何在JavaScript中将Base64字符串解码为BLOB对象?

函数将Base64编码字符串解码为新字符串,二进制数据的每个字节都有一个字符

constbytecharacters=atob(b64Data);
每个字符的代码点(charCode)将是字节的值。我们可以通过为字符串中的每个字符使用
.charCodeAt
方法来创建字节值数组

constbytenumbers=新数组(byteCharacters.length);
for(设i=0;i
通过将此字节值数组传递给
Uint8Array
构造函数,可以将其转换为实类型字节数组

const byteArray=新的UINT8数组(字节数);
反过来,可以通过将其包装在数组中并将其传递给
BLOB
构造函数,将其转换为BLOB

constblob=newblob([byteArray],{type:contentType});
上面的代码有效。但是,通过在较小的片中处理
byteCharacters
,而不是一次全部处理,可以稍微提高性能。在我粗略的测试中,512字节似乎是一个很好的切片大小。这为我们提供了以下功能

const b64toBlob=(b64Data,contentType='',sliceSize=512)=>{
常量ByTechCharacters=atob(B64数据);
常量字节数组=[];
for(让offset=0;offset
const blob=b64toBlob(b64Data,contentType);
const blobUrl=URL.createObjectURL(blob);
window.location=blobUrl;
完整示例:
const b64toBlob=(b64Data,contentType='',sliceSize=512)=>{
常量ByTechCharacters=atob(B64数据);
常量字节数组=[];
for(让offset=0;offset优化(但可读性较差)实现:

函数base64toBlob(base64Data,contentType){
contentType=contentType | |“”;
var-sliceSize=1024;
var byteCharacters=atob(base64Data);
var bytesLength=byteCharacters.length;
var slicescont=Math.ceil(字节长度/切片大小);
var byteArray=新阵列(切片器);
对于(var sliceIndex=0;sliceIndex
对于图像数据,我发现使用canvas.toBlob(异步)更简单


对于所有浏览器支持,尤其是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
    }
}

我注意到InternetExplorer11在像Jeremy建议的那样对数据进行切片时速度非常慢。Chrome也是如此,但InternetExplorer在将切片数据传递给Blob构造函数时似乎有问题。在我的机器上,通过5MB的数据会使InternetExplorer崩溃,内存消耗也会急剧增加。Chrome很快就创建了这个blob

运行以下代码进行比较:

var byteArrays = [],
    megaBytes = 2,
    byteArray = new Uint8Array(megaBytes*1024*1024),
    block,
    blobSlowOnIE, blobFastOnIE,
    i;

for (i = 0; i < (megaBytes*1024); i++) {
    block = new Uint8Array(1024);
    byteArrays.push(block);
}

//debugger;

console.profile("No Slices");
blobSlowOnIE = new Blob(byteArrays, { type: 'text/plain'});
console.profileEnd();

console.profile("Slices");
blobFastOnIE = new Blob([byteArray], { type: 'text/plain'});
console.profileEnd();
var bytearray=[],
兆字节=2,
byteArray=新的UINT8阵列(兆字节*1024*1024),
块
blobSlowOnIE,blobFastOnIE,
我
对于(i=0;i<(兆字节*1024);i++){
块=新的UINT8阵列(1024);
推(块);
}
//调试器;
控制台配置文件(“无切片”);
blobSlowOnIE=newblob(bytearray,{type:'text/plain'});
console.profileEnd();
控制台配置文件(“切片”);
blobFastOnIE=newblob([byteArray],{type:'text/plain'});
console.profileEnd();
所以我决定在一个函数中包含Jeremy描述的两种方法。这要归功于他

function base64toBlob(base64Data, contentType, sliceSize) {

    var byteCharacters,
        byteArray,
        byteNumbers,
        blobData,
        blob;

    contentType = contentType || '';

    byteCharacters = atob(base64Data);

    // Get BLOB data sliced or not
    blobData = sliceSize ? getBlobDataSliced() : getBlobDataAtOnce();

    blob = new Blob(blobData, { type: contentType });

    return blob;


    /*
     * Get BLOB data in one slice.
     * => Fast in Internet Explorer on new Blob(...)
     */
    function getBlobDataAtOnce() {
        byteNumbers = new Array(byteCharacters.length);

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

        byteArray = new Uint8Array(byteNumbers);

        return [byteArray];
    }

    /*
     * Get BLOB data in multiple slices.
     * => Slow in Internet Explorer on new Blob(...)
     */
    function getBlobDataSliced() {

        var slice,
            byteArrays = [];

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

            byteNumbers = new Array(slice.length);

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

            byteArray = new Uint8Array(byteNumbers);

            // Add slice
            byteArrays.push(byteArray);
        }

        return byteArrays;
    }
}
函数base64toBlob(base64Data、contentType、sliceSize){
var字节字符
function base64toBlob(base64Data, contentType, sliceSize) {

    var byteCharacters,
        byteArray,
        byteNumbers,
        blobData,
        blob;

    contentType = contentType || '';

    byteCharacters = atob(base64Data);

    // Get BLOB data sliced or not
    blobData = sliceSize ? getBlobDataSliced() : getBlobDataAtOnce();

    blob = new Blob(blobData, { type: contentType });

    return blob;


    /*
     * Get BLOB data in one slice.
     * => Fast in Internet Explorer on new Blob(...)
     */
    function getBlobDataAtOnce() {
        byteNumbers = new Array(byteCharacters.length);

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

        byteArray = new Uint8Array(byteNumbers);

        return [byteArray];
    }

    /*
     * Get BLOB data in multiple slices.
     * => Slow in Internet Explorer on new Blob(...)
     */
    function getBlobDataSliced() {

        var slice,
            byteArrays = [];

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

            byteNumbers = new Array(slice.length);

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

            byteArray = new Uint8Array(byteNumbers);

            // Add slice
            byteArrays.push(byteArray);
        }

        return byteArrays;
    }
}
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...
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;
   }
};
function makeblob(dataURL) {
    const BASE64_MARKER = ';base64,';
    const parts = dataURL.split(BASE64_MARKER);
    const contentType = parts[0].split(':')[1];
    const raw = window.atob(parts[1]);
    const rawLength = raw.length;
    const uInt8Array = new Uint8Array(rawLength);

    for (let i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
    }

    return new Blob([uInt8Array], { type: contentType });
}
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);
    });
}
const byteArray = new Buffer(base64String.replace(/^[\w\d;:\/]+base64\,/g, ''), 'base64');