Split file with JavaScript or jQuery

file, javascript, jquery, split, upload

Solution

Since you're using `FormData`, which is a fairly new technology, I'll show you something with new technologies as well.

First, read the file with a `FileReader` object:

var fr = new FileReader(), buf, file = $('#fileUpload')[0].files[0];
fr.onload = function(e) {
    buf = new Uint8Array(e.target.result);
};
fr.readAsArrayBuffer(file);

Then you can create a `Blob` for each splitted part (`1e6` bytes long each):

for (var i = 0, blobs = []; i < buf.length; i += 1e6)
    blobs.push(new Blob([buf.subarray(i, i + 1e6)]));

Finally, you can add all your `Blob`s to your `FormData` object:

var formData = new FormData();
for (var i = 0; i < blobs.length; i++)
    formData.append("slice" + i, blobs[i], file.name + ".part" + i);

You should be ok. I haven't tested it, though.

I don't know anything about the performance either. You can use `fr.readAsBinaryString` too, thus making `e.target.result` a string. This way, you can create the `Blob`s using a simple `substring`/`slice`/`substr`/whatever, but I fear there could be some problems with Unicode characters and whatnot. Plus, maybe it's slower.

Putting everything in a more coherent snippet:

$('#fileUpload').change(function() {
    // If no file is selected, there's nothing to do
    if (!this.files.length) return;

    var fr = new FileReader(), file = this.files[0];
    fr.onload = function(e) {
        splitAndSendFile(new Uint8Array(e.target.result), file);
    };
    fr.readAsArrayBuffer(file);
};

function splitAndSendFile(dataArray, file) {
    var i = 0, formData, blob;
    for (; i < dataArray.length; i += 1e6) {
        blob = new Blob([dataArray.subarray(i, i + 1e6)]);
        formData = new FormData();
        formData.append("fileUpload", blob, file.name + ".part" + (i / 1e6));
        $.ajax({
            url: 'script.php',
            type: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            success: function(msg){
                alert("Win: " + msg);
            },
            error: function(bla, msg){
                alert("Fail: " + msg);
            }
        });
    }
}

Note: `FormData.append` takes a third optional parameter, which should be the name of the file in case of `File` or `Blob` values. If not specified, `Blob`s may get unpredictable random file names.

Probably that parameter isn't standard, and it's not mentioned in the MDN artice, but I used it in the snippet above nonetheless. Anyway, if you know what you're doing, you can have several options to specify the file name. For example, with `formData.append("filename", file.name)` or sending a custom header in the request.

Problem

I need to upload a part of a file (only the first MB). I've created a PHP script which uploads the whole file. The data (`formData` Object) is passed by a ajax call. My idea would be now to split the file with javascript (jquery). Is there any solution for my request? Current code: ``` function start(a){ //var fSize = $('#fileUpload')[0].files[0].size / 1024; var formData = new FormData(); formData.append( 'fileUpload', $('#fileUpload')[0].files[0] ); //AJAX $.ajax({ url: 'script.php', type: 'POST', data: formData, processData: false, contentType: false, success: function(msg){ alert("Win: " + msg); }, error: function(bla, msg){ alert("Fail: " + msg); } }); } ```

Original source