Paul Draper
Paul Draper

Reputation: 83255

Upload multiple files individually

I allow a user to upload multiple SVG files to my server.

<form target="my_iframe" enctype="multipart/form-data">
    <input name="file" type="file" multiple>
</form>
<div id="message"></div>

However, some users will want to upload large numbers of files. The files themselves are relatively small (<200 kB), but there could be dozens, perhaps even a hundred or so.

It will take a long time to upload and process. If anything should go wrong during the upload, we'd have to start all over again.

I've seen website with similar problems (for example, Facebook, SmugMug) upload only one file at a time.

Without plugins (Sliverlight, Flash, etc.) How can I have the user select one file, but make a different request for each? I am targeting IE9+, Chrome, and Firefox.

Something like

//DOES NOT WORK
$.each($('input').files, function(file, i, files) {
    $('input').files = [file]; //obviously flawed, since this is an Array, not a FileList
    $('#message').text('Uploading ' + i + ' of ' + files.length);
    $('form').submit();
});

(I've heard people say that this doesn't work for security reasons, though I fail to see what exploit I could do if I could shorten FileList's.)

I think I could use XHR to send multipart-encoded data myself, but if that is the right solution, I don't understand how that works, nor how to to format it.

I imagine this is not an uncommon situation, but my searches have turned up surprisingly little.

Upvotes: 3

Views: 2832

Answers (2)

Ryan
Ryan

Reputation: 852

If you don't need to support IE9 or below then using FormData is an option

var files = $('input').files;

function upload(files, i){
    if(i >= files.length) {
        $('#message').text('Done!');
        return;
    }

    $('#message').text('Uploading ' + (i+1) + ' of ' + files.length);

    var file = files[i];
    var data = new FormData();
    data.append('file',data);
    $.ajax({
        url:'/upload',
        data:data,
        contentType:false,
        processData:false,
        type:'POST',
        success:function(){
            //handle success
        },
        error:function(){
            //handle failure
        },
        complete:function(){
            upload(files, i+1);
        }
    });
}

upload(files);

Upvotes: 4

Anoop Santhanam
Anoop Santhanam

Reputation: 85

You could always find the length of the files selected, and send them by AJAX one by one. However, depending on how you implement this, AJAX would send parallel requests. It isn't clear from your question if you're looking for something that's going to upload your files one by one as each one is successfully uploaded or if you're looking for parallel uploads like I just mentioned.

But, no matter what you choose out of the two, you can still include an exception or a condition to check for failed uploads.

It would help if you could post some code.

Upvotes: 0

Related Questions