将 ArrayBuffer 推入 Array 以构建 Blob
Push ArrayBuffer in Array for constructing a Blob
我有一组 URL [URL1, URL2, URL3,...]
:每个元素都是 link 到同一文件的一个块。每个块都单独加密,使用与所有其他块相同的密钥。
我用 XMLHttpRequest
下载每个块(在 forEach
函数中)。 onload
:
- 首先解密每个块
- 然后每个块被转换成一个
ArrayBuffer
(source)
- 每个
ArrayBuffer
被推送到一个数组 (source)
- 当为每个块完成前三个步骤时(
callback
在步骤#1 上递增 var
=== array.length
),将构建一个 blob数组
- blob 使用 FileReader API & filesaver.js
保存为文件
如果是一个块的文件,一切正常。
但是对于多个块,步骤 #1 和 #2 没问题,但似乎只有最后一个 ArrayBuffer
被推送到数组。我错过了什么?
下面是我的代码
// var for incrementation in forEach funtion
var chunkdownloaded = 0;
// 'clearfileurl' is the array of url's chunks :[URL1, URL2, URL3,...]
clearfileurl.forEach(function(entry) {
var xhr = new XMLHttpRequest();
var started_at = new Date();
xhr.open('GET', entry, true);
xhr.responseType = 'text';
// request progress
xhr.onprogress = function(pe) {
if (pe.lengthComputable) {
downloaderval.set((pe.loaded / pe.total) * 100);
}
};
// on request's success
xhr.onload = function(e) {
if (this.status == 200) {
chunkdownloaded+=1;
var todecrypt = this.response;
// decrypt request's response: get a dataURI
try {
var bytesfile = CryptoJS.AES.decrypt(todecrypt.toString(), userKey);
var decryptedfile = bytesfile.toString(CryptoJS.enc.Utf8);
} catch(err) {
console.log (err);
return false;
}
//convert a dataURI to a Blob
var MyBlobBuilder = function() {
this.parts = [];
}
MyBlobBuilder.prototype.append = function(dataURI) {
//function dataURItoBlob(dataURI) {
// convert base64 to raw binary data held in a string
var byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
// var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
this.parts.push(ab);
console.log('parts', this.parts)
this.blob = undefined; // Invalidate the blob
}
MyBlobBuilder.prototype.getBlob = function() {
if (!this.blob) {
console.log (this.parts);
this.blob = new Blob(this.parts);
}
return this.blob;
};
var myBlobBuilder = new MyBlobBuilder();
myBlobBuilder.append(decryptedfile);
// if all chunks are downloaded
if (chunkdownloaded === clearfileurl.length) {
// get the blob
var FinalFile = myBlobBuilder.getBlob();
// launch consturction of a file with'FinalFile' inside FileReader API
var reader = new FileReader();
reader.onload = function(e){
// build & save on client the final file with 'file-saver' library
var FileSaver = require('file-saver');
var file = new File([FinalFile], clearfilename, {type: clearfiletype});
FileSaver.saveAs(file);
};
reader.readAsText(FinalFile);
} else {
console.log('not yet');
}
}
};
// sending XMLHttpRequest
xhr.send();
});
你需要把MyBlobBuilder
的声明去掉,试试这个:
// var for incrementation in forEach funtion
var chunkdownloaded = 0;
//convert a dataURI to a Blob
var MyBlobBuilder = function() {
this.parts = [];
}
MyBlobBuilder.prototype.append = function(dataURI, index) {
//function dataURItoBlob(dataURI) {
// convert base64 to raw binary data held in a string
var byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
// var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
this.parts[index] = ab;
console.log('parts', this.parts)
this.blob = undefined; // Invalidate the blob
}
MyBlobBuilder.prototype.getBlob = function() {
if (!this.blob) {
console.log (this.parts);
this.blob = new Blob(this.parts);
}
return this.blob;
};
var myBlobBuilder = new MyBlobBuilder();
// 'clearfileurl' is the array of url's chunks :[URL1, URL2, URL3,...]
clearfileurl.forEach(function(entry, index) {
var xhr = new XMLHttpRequest();
var started_at = new Date();
xhr.open('GET', entry, true);
xhr.responseType = 'text';
// request progress
xhr.onprogress = function(pe) {
if (pe.lengthComputable) {
downloaderval.set((pe.loaded / pe.total) * 100);
}
};
// on request's success
xhr.onload = function(e) {
if (this.status == 200) {
chunkdownloaded+=1;
var todecrypt = this.response;
// decrypt request's response: get a dataURI
try {
var bytesfile = CryptoJS.AES.decrypt(todecrypt.toString(), userKey);
var decryptedfile = bytesfile.toString(CryptoJS.enc.Utf8);
} catch(err) {
console.log (err);
return false;
}
myBlobBuilder.append(decryptedfile, index);
// if all chunks are downloaded
if (chunkdownloaded === clearfileurl.length) {
// get the blob
var FinalFile = myBlobBuilder.getBlob();
// launch consturction of a file with'FinalFile' inside FileReader API
var reader = new FileReader();
reader.onload = function(e){
// build & save on client the final file with 'file-saver' library
var FileSaver = require('file-saver');
var file = new File([FinalFile], clearfilename, {type: clearfiletype});
FileSaver.saveAs(file);
};
reader.readAsText(FinalFile);
} else {
console.log('not yet');
}
}
};
// sending XMLHttpRequest
xhr.send();
});
*编辑我还更新了追加功能以确保文件顺序正确
我有一组 URL [URL1, URL2, URL3,...]
:每个元素都是 link 到同一文件的一个块。每个块都单独加密,使用与所有其他块相同的密钥。
我用 XMLHttpRequest
下载每个块(在 forEach
函数中)。 onload
:
- 首先解密每个块
- 然后每个块被转换成一个
ArrayBuffer
(source) - 每个
ArrayBuffer
被推送到一个数组 (source) - 当为每个块完成前三个步骤时(
callback
在步骤#1 上递增var
===array.length
),将构建一个 blob数组 - blob 使用 FileReader API & filesaver.js 保存为文件
如果是一个块的文件,一切正常。
但是对于多个块,步骤 #1 和 #2 没问题,但似乎只有最后一个 ArrayBuffer
被推送到数组。我错过了什么?
下面是我的代码
// var for incrementation in forEach funtion
var chunkdownloaded = 0;
// 'clearfileurl' is the array of url's chunks :[URL1, URL2, URL3,...]
clearfileurl.forEach(function(entry) {
var xhr = new XMLHttpRequest();
var started_at = new Date();
xhr.open('GET', entry, true);
xhr.responseType = 'text';
// request progress
xhr.onprogress = function(pe) {
if (pe.lengthComputable) {
downloaderval.set((pe.loaded / pe.total) * 100);
}
};
// on request's success
xhr.onload = function(e) {
if (this.status == 200) {
chunkdownloaded+=1;
var todecrypt = this.response;
// decrypt request's response: get a dataURI
try {
var bytesfile = CryptoJS.AES.decrypt(todecrypt.toString(), userKey);
var decryptedfile = bytesfile.toString(CryptoJS.enc.Utf8);
} catch(err) {
console.log (err);
return false;
}
//convert a dataURI to a Blob
var MyBlobBuilder = function() {
this.parts = [];
}
MyBlobBuilder.prototype.append = function(dataURI) {
//function dataURItoBlob(dataURI) {
// convert base64 to raw binary data held in a string
var byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
// var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
this.parts.push(ab);
console.log('parts', this.parts)
this.blob = undefined; // Invalidate the blob
}
MyBlobBuilder.prototype.getBlob = function() {
if (!this.blob) {
console.log (this.parts);
this.blob = new Blob(this.parts);
}
return this.blob;
};
var myBlobBuilder = new MyBlobBuilder();
myBlobBuilder.append(decryptedfile);
// if all chunks are downloaded
if (chunkdownloaded === clearfileurl.length) {
// get the blob
var FinalFile = myBlobBuilder.getBlob();
// launch consturction of a file with'FinalFile' inside FileReader API
var reader = new FileReader();
reader.onload = function(e){
// build & save on client the final file with 'file-saver' library
var FileSaver = require('file-saver');
var file = new File([FinalFile], clearfilename, {type: clearfiletype});
FileSaver.saveAs(file);
};
reader.readAsText(FinalFile);
} else {
console.log('not yet');
}
}
};
// sending XMLHttpRequest
xhr.send();
});
你需要把MyBlobBuilder
的声明去掉,试试这个:
// var for incrementation in forEach funtion
var chunkdownloaded = 0;
//convert a dataURI to a Blob
var MyBlobBuilder = function() {
this.parts = [];
}
MyBlobBuilder.prototype.append = function(dataURI, index) {
//function dataURItoBlob(dataURI) {
// convert base64 to raw binary data held in a string
var byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
// var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
this.parts[index] = ab;
console.log('parts', this.parts)
this.blob = undefined; // Invalidate the blob
}
MyBlobBuilder.prototype.getBlob = function() {
if (!this.blob) {
console.log (this.parts);
this.blob = new Blob(this.parts);
}
return this.blob;
};
var myBlobBuilder = new MyBlobBuilder();
// 'clearfileurl' is the array of url's chunks :[URL1, URL2, URL3,...]
clearfileurl.forEach(function(entry, index) {
var xhr = new XMLHttpRequest();
var started_at = new Date();
xhr.open('GET', entry, true);
xhr.responseType = 'text';
// request progress
xhr.onprogress = function(pe) {
if (pe.lengthComputable) {
downloaderval.set((pe.loaded / pe.total) * 100);
}
};
// on request's success
xhr.onload = function(e) {
if (this.status == 200) {
chunkdownloaded+=1;
var todecrypt = this.response;
// decrypt request's response: get a dataURI
try {
var bytesfile = CryptoJS.AES.decrypt(todecrypt.toString(), userKey);
var decryptedfile = bytesfile.toString(CryptoJS.enc.Utf8);
} catch(err) {
console.log (err);
return false;
}
myBlobBuilder.append(decryptedfile, index);
// if all chunks are downloaded
if (chunkdownloaded === clearfileurl.length) {
// get the blob
var FinalFile = myBlobBuilder.getBlob();
// launch consturction of a file with'FinalFile' inside FileReader API
var reader = new FileReader();
reader.onload = function(e){
// build & save on client the final file with 'file-saver' library
var FileSaver = require('file-saver');
var file = new File([FinalFile], clearfilename, {type: clearfiletype});
FileSaver.saveAs(file);
};
reader.readAsText(FinalFile);
} else {
console.log('not yet');
}
}
};
// sending XMLHttpRequest
xhr.send();
});
*编辑我还更新了追加功能以确保文件顺序正确