FunctionSource, Your Source for Developer News

Resume: How to not lose 90% of your upload

Posted by Dion Almaer about a year ago on example file upload

Simon Speich has a nice tutorial over on Mozilla Hacks regarding the new slice() API, and how it can be used to resume an upload when you combine it with the File APIs:

// Assuming that the request to fetch the already written bytes has just
// taken place and xhr.result contains the response from the server.
var start = xhr.result.numWrittenBytes;
var length = file.size - start;
var chunk = file.slice(start, length);
 
var req = new XMLHttpRequest();
req.open('post', 'fnc.php?fnc=resume', true);
 
req.setRequestHeader("Cache-Control", "no-cache");
req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
req.setRequestHeader("X-File-Name", file.name);
req.setRequestHeader("X-File-Size", file.size);
 
req.send(chunk);

This code is paired to server side magic (a PHP version is shown), and Simon discusses how to take things a little further and recover from a crash:

You can take the pause-and-resume functionality even a step further. It is possible (at least in theory) to even recover uploading after an unexpected closing or crashing of the browser. The problem is that after the browser was closed, the file object, which was read into memory, is lost. The user would have to re-pick or drag over the file again first, before being able to slice the file to resume the upload.

Instead, you could use the new IndexedDB API and store the file before any uploading is done. Then after a browser crash, load the file from the database, slice into the remaining chunk and resume the upload.