Search code examples
javascriptphpajaxxmlhttprequest

Nonsensical values of loaded and total in AJAX file upload


I am trying to build a progress bar for multiple files drag and drop upload by combining code from tutorial on multiple files drag and drop uploading and tutorial on progress bar uploading.

Javascript part is:

var dropzone = document.getElementById("dropzone");

function updateProgress(e){
  document.getElementById("progress").innerHTML = e.loaded + " of " + e.total;
}

function upload(files){
  var formData = new FormData(),
      xhr = new XMLHttpRequest(),
      x;
  for(x = 0; x < files.length; x++){
    formData.append("file[]", files[x]);
  }
  xhr.addEventListener("progress", updateProgress, false);
  xhr.open("post", "upload.php");
  xhr.send(formData);
}    

dropzone.ondrop = function(e){
  e.preventDefault();
  this.className = "dropzone";
  upload(e.dataTransfer.files);
}

dropzone.ondragover = function(){
  this.className = "dropzone dragover";
  return false;
}

dropzone.ondragleave = function(){
  this.className = "dropzone";
  return false;
}

And upload.php is simply:

<?php
if(!empty($_FILES["file"]["name"][0]))
  foreach($_FILES["file"]["name"] as $position => $name)
    move_uploaded_file($_FILES["file"]["tmp_name"][$position], "uploads/".$name);
?>

For start, before making actual progress bar, I just want to show the number of uploaded and total bytes. However, function updateProgress doesn't get called if upload.php echoes nothing and otherwise (e.g. if I add echo "something";) e.loaded and e.total are small numbers of same value, unrelated to file size.

File upload itself works fine, even with large files (few hundred MBs). With large files, I've noticed that function updateProgress is called only once - after the upload is complete.

Why is this event handling behaving like this and how to fix it?


Solution

  • You are setting a progress handler for download, to set one for upload use

    xhr.upload.addEventListener("progress", updateProgress, false);