title: Why might XMLHttpRequest ProgressEvent.lengthComputable be false?
body: <p>I'm trying to implement a upload progress bar the HTML5 way, by using the XMLHttpRequest level 2 support for progress events.</p>
  
  <p>In every example you see, the method is to add an event listener to the progress event like so:</p>
  
  <pre><code>req.addEventListener("progress", function(event) {
      if (event.lengthComputable) {
          var percentComplete = Math.round(event.loaded * 100 / event.total);
          console.log(percentComplete);
      }
  }, false);
  </code></pre>
  
  <p>Such examples always seem to assume that event.lengthComputable will be true. After all, the browser knows the length of the request it's sending, surely?</p>
  
  <p>No matter what I do, event.lengthComputable is false. I've tested this in Safari 5.1.7 and Firefox 12, both on OSX.</p>
  
  <p>My site is built using Django, and I get the same problem on my dev and production setups.</p>
  
  <p>The full code I'm using to generate the form upload is shown below (using jQuery):</p>
  
  <pre><code>form.submit(function() {
      // Compile the data.
      var data = form.serializeArray();
      data.splice(0, 0, {
          name: "file",
          value: form.find("#id_file").get(0).files[0]
      });
      // Create the form data.
      var fd = new FormData();
      $.each(data, function(_, item) {
          fd.append(item.name, item.value);
      });
      // Submit the data.
      var req = new XMLHttpRequest();
      req.addEventListener("progress", function(event) {
          if (event.lengthComputable) {
              var percentComplete = Math.round(event.loaded * 100 / event.total);
              console.log(percentComplete);
          }
      }, false);
      req.addEventListener("load", function(event) {
          if (req.status == 200) {
              var data = $.parseJSON(event.target.responseText);
              if (data.success) {
                  console.log("It worked!")
              } else {
                  console.log("It failed!")
              }
          } else {
              console.log("It went really wrong!")
          }
      }, false);
      req.addEventListener("error", function() {
          console.log("It went really really wrong!")
      }, false);
      req.open("POST", "/my-bar/media/add/");
      req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
      req.send(fd);
      // Don't really submit!
      return false;
  });
  </code></pre>
  
  <p>I've been tearing my hair out for hours on this. Any help appreciated!</p>