« Mini Cooper Coming Soon... | Main | R.E.M. Plays SXSW »

February 6, 2008

Inline Web Browser File Upload

I'm tackling a project where we're trying to simplify the way users add attachments to various parts of our site. This involves some reorganizing of workflow, but also could benefit from a more modern mechanism for uploading files.

Our art director (where this idea started) pointed me to SWFUpload, which seems like a very slick option using Flash. Initially I thought this was the right way to go.

However, after some asking around I was pointed to jqUploader, a jQuery plugin that also uses a bit of Flash. Since we already use jQuery I figured this might be a good option since we're versed in jQuery and already have some architecture in place to readily support jQuery plugins.

But then in discussions with other members on our engineering team I was encouraged to look at pure JavaScript methods for doing this, where a standard form is submitted and Ajax uploads the file with a second Ajax request going back to get progress indicators. I have been able to find a few articles about doing this, but not a drop-in solution like SWFUpload or jqUploader.

While digging around for pure JavaScript solution I stumbled into this over on ThinkingPHP, a note on the top of an older post about JavaScript/Ajax file uploading:

Important Warning: The code presented her was an experiment of mine that I did over a year ago. In the meantime flash based file uploaders have become a much better weapon of choice when it comes to unobtrusive upload experience enhancing. As of now I highly recommend you to checkout either jqUploader or SWFUpload as I am no longer able to provide support for this solution. Setting them up should be multiple times easier and will require no Perl or (Cake)PHP on the server side.

LightLoader is another pure Ajax uploader/file progress indicator. Runs PHP on the server side. Uber-uploader is another one, server side stuff available in a number of open source languages.

Now, for some digging around in our code to try some of these out...

jqUploader Notes

I've gotten the jQuery plugin working, but there are some things that I don't like. First, the Flash UI has some issues. There are a few settings that allow you to control presentation, but not enough. I can control the background color, and some portions of the text that is displayed for the user. The positioning of the input box and message area on the Flash are indented so they don't align with other elements on the page. I think it's annoying that an long empty rectangle sits in the widget at all times. When you upload a file you realize that it's the progress bar, but I don't think there's a need to show it unless you're actually uploading.

I also don't like the fact that you browse and then upload, independent of what is happening on the form. It seems to make more sense to "browse" and then "save" the page, with the upload happening as a part of the save.

Last complaint, there are a lot of reported issues that really make for uncertainty about using this solution. I'm digging around at the HTTPS issues that seems to cause an I/O error when trying to use a secure connection. These documents have some clues about what is going on. Oh, and here's a good article about how to debug Flash via a browser plugin. More info on the HTTPS problem. As far as HTTPS, I have confirmed the following snips from the comments on this document to be true in Flash 9:

!! Warning for Mac player !! When you use the FileReference.upload(), the class add the port 80 to the request! For example, with the url http://www.nectil.com/upload.php the real query will be sent at http://www.nectil.com:80/upload.php. Please, Flash player team, remove the :80 !!! It's impossible to send it over HTTPS for mac users!
...
I have had a similar situation using HTTPS on both Mac and Windows Flash Players. I can get .upload to work correctly on Mac Safari and Windows IE through HTTPS if I put the fully-qualified path, including the SSL port 443, in the url parameter like so:

file.upload("https://www.somesite.com:443/cgi-bin/someScript.sh");

My final tests demonstrate that with Flash file uploads, HTTPS is not reliable. With the workaround you can get it to work in some browsers, but not all.

This all being said, it is really simple to put jqUploader on the page and get inline uploads going in just a few steps, so long as you're using HTTP.

SWFUpload Notes

I got SWFUpload working, and really like the way it fits right into our form using standard HTML elements. However, there is the same issue with HTTPS. SWFUpload mentions it in the documentation's Known Issues:

There have been some reports that the Flash Player cannot upload through SSL. The issue has not been pinned down but uploading over SSL may be unreliable.

I can get the upload to work just fine using standard HTTP, but HTTPS fails with an I/O error. We run strictly in HTTPS on our production site.

Pure Ajax Notes

I was hoping that one of the Flash "drop-in" solutions would do the trick, but it seems like the pure Ajax method is going to get some attention. These two articles were send to me as other sources of documentation.

Posted by mike at February 6, 2008 12:50 PM