Posted by & filed under Javascript/YUI/jQuery, Web Development.

There seems to be a number of different forum threads and webpages that deal with constructing AJAX based file uploader tools that don’t require that the page be completely reloaded to process the file upload. In addition, this is further complicated by the desire for progress bars and other forms of feedback.

This posting will attempt to deal with the basic strategies and choices available for providing this functionality. We won’t delve into actual code, but rather (hopefully) help point you in the right direction to tackle this on your own!

There seems to be a number of different forum threads and webpages that deal with constructing AJAX based file uploader tools that don’t require that the page be completely reloaded to process the file upload. In addition, this is further complicated by the desire for progress bars and other forms of feedback.

The most important caveat to understand is that AJAX based file uploaders are simply not possible the way one would expect. You can’t simply include the “enctype” property in an AJAX call and expect the upload to be processed with an AJAX post (or get). There are a few reasons for this, as far as we understand. One is the fact that different browsers have different file selection mechanisms, and therefore it is difficult to use Javascript to get the file name/path of a file in a consistent way across different browsers. Second is security – if a user’s browser were to be compromised this could perhaps result in the files on the user’s drive being somehow exposed. Thirdly, Javascript right now simply cannot manually encode files via AJAX. Perhaps a new web standard is in order to address all of these challenges? On the iOS devices, an Objective-C based API is needed to select and upload media stored on these devices, maybe some sort of similar bridge should be devised and ratified as a web standard?

Workarounds

No AJAX

One workaround is to simply concede this functionality and initialize a standard form submit via Javascript, resulting in a complete page load.

Use of an iframe

Another known workaround is to do the same, but to include the “target” attribute in the form tag that targets an iframe that you can keep concealed via CSS. Once the form submission has been received by the iframe you can call a parent function to “break out” of the frame via the following:

parent.yourFunction(arguments);

If you do this, don’t forget that this Javascript will have to be attached to the page being rendered by the iframe, not to any of its parent pages.

This solution is a little bit clunky in part because it uses frames which are themselves rather clunky. In fact, frames are generally discouraged as evidenced by the fact that the form “target” attribute is considered deprecated. However, it is still supported in all major browsers so long as you do not use the “strict” doctype. If you don’t mind instead using the transitional doctype, this is probably your best overall solution short of resorting to using Flash (see below)…

YUI IO Library

The YUI 3 IO library provides an easy way to handle uploading files within a form using an iframe with an example you can easily copy and paste and customize to your liking here. Using this library is recommended, particularly if you have other reasons to use YUI (and there are definitely many), since it does all of the heavy lifting for you, above. The example provided here is easy to follow and setup to work with your forms.

Flash

If you have used WordPress you will notice that its default uploader is Flash based. Flash will handle not only uploading tools that do not require your standard form submission, but also progress bars. The YUI IO/uploader library supports using either Flash or a hidden iframe.

Progress bars

If you are interested in providing a progress bar in PHP, your options are somewhat limited. You can use the APC utility to track file uploads and include a setTimeout to check on your upload periodically and update the progress bar accordingly, but this is a little ugly and also does not work with PHP CGI installations. If you use PHP and you really want to provide a progress bar, your best bet is probably to stick with Flash. This is what the WordPress team evidently decided to do since their default uploader is Flash based.