Sunday, March 10, 2013

Chrome’s XMLHttpRequest (XHR ) abort issue while uploading multiple files.

I developed a file uploading component using HTML5 File API and XMLHttpRequest(XHR) .One of the main requirements was, the user should be able to abort/cancel one or more uploading request from the list of files that are being uploaded.

Please check my previous post of “How to Upload Files with HTML5 File API and XMLHttpRequest(XHR)”

While I was implementing abort functionality, I came across an issue that the Chrome Browser did not allow aborting a request when multiple files are being uploaded. And this turned out to be a bug
http://code.google.com/p/chromium/issues/detail?id=154643
https://bugs.webkit.org/show_bug.cgi?id=106937

The bug reports explain that it’s something to do with cached resource. So it tried to make every POST request to be unique. As I don’t allow the user to select files that has same names, I was able to make the XHR request unique with appending the file name in each request.

The initial one was:
xhr.open('POST', "", true);

After the modification: 

xhr.open('POST', "?upid=" + file.name, true);
here, ‘upid’ is just a parameter name that I use .

So the code that makes the XHR request would be
if ($.browser.chrome) {
 try {
  /*
   * XHR.abort() is not working properly in Chrome ( aborting
   * a file upload while uploading multiple files parallely)
   */
  // Bug
  // :http://code.google.com/p/chromium/issues/detail?id=154643
  // Bug :http://trac.webkit.org/changeset/140174
  // Bug :https://bugs.webkit.org/show_bug.cgi?id=106937
  
  xhr.open('POST', "?upid=" + file.name, true);
  xhr.send(formData);
 } catch (e) {
 }
} else {
 xhr.open('POST', "", true);
 xhr.send(formData);
}
This approach really worked for me and hope it helps you too

Saturday, March 9, 2013

Uploading Files with HTML5 File API and XMLHttpRequest(XHR)

Go to >> Java Tutorials

Target audience: Beginners, Intermediate

I have been developing a file upload component using HTML5 File API , XMLHttpRequest(XHR) and JSF. I would like to share here only the client side part.

The Upload component is

  1. Able to select multiple files of any format. 
  2. Able to keep previously select files, meaning that it should be able to let the user select files one by one and then he should be able to upload whole files later. 
  3. Able to show/restrict/validate selected files from client side (Using HTML5 and JavaScript APIs). Here, I just only show the file size, you can modify this code to validate the file size. 
  4. Able to show the upload progress. Here, I just show the percentage. You can modify the code to make is as a progress bar 
This is how it would look like


I break the major parts of the implementation bellow

  1. When a user selects file or files, the prepare(); method will be called. Its set be invoked while onchange event on the file input element is fired. This prepare() method will show the selected file/files. It creates a table and populates it with files selections. The table has three(3) columns. First column is to show the file name and to keep a hidden image. The hidden img(img.file) element is used to hold the file selections. Second column is to show the file size. The third column is show the progress. 
  2. When the user clicks the upload button after he makes the file selections, the submitUpload() method will be called. Its set be invoked while click event on the submit button element is fired. It grabs all files from the hidden images (img.file) and then create XHR request for each files. The XHR’s events are used to update the progress of the file uploads.

The code is shown bellow.


HTML 5 XHR ( XMLRequestObject) mutiple file upload