Ich habe festgestellt, dass Internet Explorer 11 extrem langsam wird, wenn die Daten so wie von Jeremy vorgeschlagen aufgeteilt werden. Das trifft auch auf Chrome zu, aber Internet Explorer scheint ein Problem zu haben, wenn die aufgeteilten Daten an den Blob-Konstruktor übergeben werden. Auf meinem Rechner lässt Internet Explorer abstürzen, wenn 5 MB Daten übergeben werden und der Speicherverbrauch steigt enorm. Chrome erstellt den Blob dagegen sofort.
Führen Sie diesen Code zum Vergleich aus:
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("Ohne Slices");
blobSlowOnIE = new Blob(byteArrays, { type: 'text/plain'});
console.profileEnd();
console.profile("Slices");
blobFastOnIE = new Blob([byteArray], { type: 'text/plain'});
console.profileEnd();
Also beschloss ich, beide von Jeremy beschriebenen Methoden in einer Funktion zu verwenden. Credits gehen an ihn dafür.
function base64toBlob(base64Data, contentType, sliceSize) {
var byteCharacters,
byteArray,
byteNumbers,
blobData,
blob;
contentType = contentType || '';
byteCharacters = atob(base64Data);
// BLOB-Daten abrufen, geschnitten oder nicht
blobData = sliceSize ? getBlobDataSliced() : getBlobDataAtOnce();
blob = new Blob(blobData, { type: contentType });
return blob;
/*
* Die BLOB-Daten in einem Stück abrufen.
* => Schnell in Internet Explorer bei 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];
}
/*
* Die BLOB-Daten in mehreren Stücken abrufen.
* => Langsam in Internet Explorer bei 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);
// Slice hinzufügen
byteArrays.push(byteArray);
}
return byteArrays;
}
}