2

I'm currently working on a file uploader that will eventually be able to loop through multiple files and tally up the total amount of bytes to upload by looping through them all beforehand. However, I've come across the following problem...

If I compare the file size returned by target.files[n].size from a file input and the value returned by XHR's upload progress listener event e.total, they don't seem to be the same. XHR's e.total ends up being several hundred bytes higher sometimes.

Could someone explain why this is happening? This happens regardless of what browser I'm using to test the Javascript.

<form enctype="multipart/form-data" method="post">
    <input type="file"  multiple="" />
</form>
function uploadfiles() {

    var files = $('input[type=file]').prop('files');
    var total_size = files[0].size;
    
    console.log("size from file.size = " + total_size);
    
    var fd = new FormData();
    fd.append('file', files[0]);

    $.ajax({
        url: '/ajax/uploadfiles.php',
        type: 'post',
        processData: false,
        contentType: false,
        data: fd,
        dataType: 'json',
        xhr: function() {

            var xhr = new XMLHttpRequest();
            xhr.upload.addEventListener('progress', function(e){
                console.log("xhr size = " + e.total);
            }, false);
            return xhr;
            
        }
    }); // ajax
                
};
ZachB
  • 13,051
  • 4
  • 61
  • 89
Ken
  • 499
  • 6
  • 18
  • 1
    https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent/total *"When downloading a resource using HTTP, this only represent the content itself, not headers and other overhead."* So conversely, an upload would count the headers and overhead. – Taplar Feb 28 '18 at 22:07
  • Thanks for the quick reply. Is there any way I can account for that overhead so I can have an overall progress value for multiple files that will be uploaded separately...? – Ken Feb 28 '18 at 22:14
  • Unfortunately I'll have to point you to another developer as I've never dealt with progress handling myself. – Taplar Feb 28 '18 at 22:23
  • OK, I think I have a workaround for that anyway but, if a proper way of accounting for the header overhead exists then that would be better of course. You didn't leave the documentation as an answer so I can't mark it as accepted. – Ken Feb 28 '18 at 22:57
  • @Taplar it doesn't include headers; the discrepancy is from encoding. See my answer. – ZachB Jan 20 '21 at 19:45

1 Answers1

0

The ProgressEvent's total property counts all body bytes, which for file uploads typically means multipart/form-data encoding. (See step 6.6 of section 4.5 of the fetch standard; same applies for XHR.)

It's possible to calculate the total body bytes ahead of time if you do your own encoding, but I don't think it's possible to determine it from a FormData instance. It's far easier to just use the ProgressEvent's total value instead of the file size.

ZachB
  • 13,051
  • 4
  • 61
  • 89