Andy Mills Andy Mills - 6 months ago 40
Ajax Question

File Upload Progress Event not firing, although file uploads

I've seen a few posts on here with similar issues, but I can't seem to get this solved. Basically, I have an AJAX file uploader that doesn't seem to call the progress event. The other events fire just fine, and the file uploads exactly as I expect it, but the progress event isn't being called. The javascript is shown below:

$('input[name=avatar_upload]').change(function(e) {
// Get the Form
var setupForm = $('#setup-member-form');

// Get the File Array
var file = document.getElementById('avatar-upload').files[0];

// Show the File Upload Progress
$('#avatar-upload-progress').show();

// Create a new Form Data Object
var formData = new FormData();

// Add the File
formData.append('avatar', file);

// Create the AJAX Object
var ajax = new XMLHttpRequest();

// Add the Event Listeners
ajax.addEventListener("loadstart", function(evt) {
// Do something in here...
$('#output').append("upload starting...\n");
}, false);
ajax.addEventListener("progress", function(evt) {
var percentLoaded = (evt.loaded / evt.total) * 100;
$('#output').append(percentLoaded + "% loaded\n");
$('#avatar-upload-progress .ui-progress-bar-inner').animate({'width' : percentLoaded + '%'}, 400);
}, false);
ajax.addEventListener("load", function(evt) {
// Do something in here when loaded...
$('#output').append("upload complete!");
}, false);

// Open the Form
ajax.open("POST", $('input[name=upload_handler]').val());
ajax.send(formData);
});


At first I thought it might just be because the file was too small for the progress event to have a chance to fire, but I've tried it with larger files, and the load event fires, then there is a few seconds pause, then the complete event fires.

If anyone has any ideas, please let me know!

Answer

Just tested this, and for uploads you have to use XMLHttpRequest.upload, as attaching the events directly to XMLHttpRequest only fires once when uploading.

It's also explained in the documentation on MDN

$('#avatar-upload').on('change', function () {
    var file = document.getElementById('avatar-upload').files[0];

    $('#avatar-upload-progress').show();
    var formData = new FormData();
    formData.append('avatar', file);

    var ajax = new XMLHttpRequest();

    ajax.upload.addEventListener("loadstart", function (evt) {
        $('#output').append("upload starting...\n");
    }, false);

    ajax.upload.addEventListener("progress", function (evt) {
        var percentLoaded = (evt.loaded / evt.total) * 100;
        $('#output').append(percentLoaded + "% loaded\n");
        $('#avatar-upload-progress .ui-progress-bar-inner').animate({
            'width': percentLoaded + '%'
        }, 400);
    }, false);

    ajax.upload.addEventListener("load", function (evt) {
        $('#output').append("upload complete!");
    }, false);

    ajax.open("POST", $('input[name=upload_handler]').val());
    ajax.send(formData);
});
Comments