I am trying to send a large file to a server, so I am using the chunking technique in order to do it in a robust way.
private readonly sendChunk = (file: File, progressModel: ProgressResponseModel): void => {
const offset = progressModel.Offset;
if (offset > file.size)
throw new Error("Offset cannot be greater than the file size");
const expectedSize = progressModel.ExpectedChunkSize;
const blobChunk = file.slice(offset, expectedSize);
const xhr = new XMLHttpRequest();
xhr.onload = (ev: Event): void => {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
const progress = this.progressFromText(xhr.responseText);
if (progress.Offset >= 0) {
this.sendChunk(file, progress);
}
console.log(`${progress.Progress} %`);
}
}
xhr.open("POST", this._uploadChunkUrl, true);
xhr.send(blobChunk);
}
The server sends back where to start the new chunk from and how big it should be. The above function is executed in a recursive manner as you can see.
However, if the file requires more than 1 chunk to be sent, the second time I call const blobChunk = file.slice(offset, expectedSize);
I get an empty chunk (length 0).
I can guarantee that the file
arg is always valid (when console.log
ed).
I've seen this question, but I am sure my file is not removed or renamed. I've also seen this issue. I get the same behavior for both Chrome and Firefox (latest versions), also Edge.
Thanks!
UPDATE Okay, so I did a dummy method in order to isolate this issue:
readonly chunkIt = (file: Blob): void => {
var offset = 0;
var length = 512 * 1024;
while (offset >= 0) {
const blobChunk = file.slice(offset, length);
console.log(blobChunk);
offset += length;
if (offset > file.size) offset = -1;
}
}
And using it:
$("input[name='fileUpload']").on("change", (e) => {
const files = e.target.files;
if (typeof files === "undefined" || files === null || files.length === 0)
e.preventDefault();
const file = files[0];
this._client.chunkIt(file);
});
Logs a correct Blob
only the first time, the following are all empty.
SOLVED
From this issue - Splitting a File into Chunks with Javascript it turned out that I've forgot to offset my end
index.