I want to send file chunks to server async to server (MVC action in a controller). I want to ensure that requests that I am sending through JS can be cancelled midway. I know about AJAX abort() but I think since the requests are async I am having little option other than setting a Session variable on MVC controller which rejects all blocks coming to it after being set. Please tell me the optimal way to do this. Can you tell me whether abort() can be used in this scenario and if yes then how? What are the other strategies I can follow to make this better?
My JS method is:
$.ajax({
type: "POST",
context: this,
async: true,
url: "/Home/PrepareMetaData",
data: { "blocksCount": totalNumberOfBlocks, "fileName": file.name, "fileSize": file.size },
dataType: "json",
error: function () {
statusLabel.innerHTML = 'Failed to send file meta data. Retry after some time.';
progressElement.setAttribute('hidden', 'hidden');
},
success: function () {
var start = 0;
var end = Math.min(blockLength, file.size) - 1;
var incrimentalIdentifier = 1;
while (start <= file.size - 1 && !window.haltExecution) {
var data = new FormData();
data.append(incrimentalIdentifier, file.webkitSlice(start, end));
xhr = $.ajax({
async: true,
url: '/Home/UploadBlock',
context: this,
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
error: function (notice) {
statusLabel.innerHTML = notice;
progressElement.setAttribute('hidden', 'hidden');
haltExecution = true;
},
success: function (notice) {
blockCounter += 1;
if (notice.error || notice.isLastBlock) {
this.message = notice.message;
}
if (notice.error || blockCounter == totalNumberOfBlocks) {
statusLabel.innerHTML = this.message;
progressElement.setAttribute('hidden', 'hidden');
haltExecution = true;
}
}
});
start = end + 1;
end = Math.min(start + blockLength, file.size) - 1;
incrimentalIdentifier++;
}
}
});
Thanks.
Edit:
I agree with the comments but if I make the Ajax request synchronous then I would be going against the nature of Ajax and would also be risk performance degrade. Another issue would be stuck UI. Even if I use Web Worker for this it would make my code async as it is now. What are your views??
Here is a rewrite which should point you in the right direction. You need to send each subsequent chunk in the success handler of the previous one, rather than sending them all at once. This is just a quick hack around what you already had so it’s not perfect, but it should help.