Since 2018, there is a JavaScript API for this, first you need to slice the file using Blob.slice or its prefix version, then send the pieces using FormData. The server needs to add a piece to the end of the file, so before you start, you will need to delete the old file if it exists.
In my project, I use this code:
Uploader.prototype.upload_by_chunks = function upload_by_chunks(file, path, chunk_size) { var self = this; chunk_size = chunk_size || 1048576; // 1MB var defered = $.Deferred(); function slice(start, end) { if (file.slice) { return file.slice(start, end); } else if (file.webkitSlice) { return file.webkitSlice(start, end); } } var i = 0; function process(start, end) { if (start < file.size) { var chunk = slice(start, end); var formData = new FormData(); formData.append('file', chunk, file.name); formData.append('token', self.token); formData.append('path', path); $.ajax({ url: 'lib/upload.php?append=1', type: 'POST', success: function(response) { if (response.error) { self.error(response.error); defered.reject(); } else { process(end, end+chunk_size); } }, error: function(jxhr, error, status) { self.error(jxhr.statusText); defered.reject(); }, data: formData, cache: false, contentType: false, processData: false }); } else { self.leash.terminal.echo('File "' + file.name + '" uploaded.'); defered.resolve(); } } var fname = path + '/' + file.name; this.leash.service.unlink(self.token, fname)(function(err, del) { if (err) { self.error(err); defered.reject(); } else { process(0, chunk_size); } }); return defered.promise(); };
before loading the pieces I check this condition:
file.size > self.leash.settings.upload_max_filesize
constant is taken from php:
$upload_limit = intval(ini_get('upload_max_filesize')) * 1024 * 1024;