Flickr Uploadr: Improving Browser-based File Uploads with YUI Uploader

By Scott SchillerFebruary 26th, 2009

Traditionally, file uploading in the browser has been awkward, slow and error-prone. File selection is done one at a time and monitoring progress of the upload is difficult. There are no simple callbacks for total bytes, progress, error handling and so on, restricting the developer’s ability to provide meaningful messaging on the UI end.

Conveniently, existing browser plug-ins such as Flash can be used to provide or enhance certain functionality which browsers themselves do not support. The combination of Flash and JavaScript allows for batch file selection, progress and error reporting, and speedier uploading.

In a typical Flash-driven uploader, Flash provides the core service and provides callbacks to JavaScript-land with status updates, messaging and so on. JavaScript then updates an HTML and CSS-driven UI. Flash-JavaScript communication is made possible by Flash’s ExternalInterface API, introduced with Flash 8. Several projects have implemented uploaders based on this approach, including the YUI Uploader control and SWFUpload among others. While developing against ExternalInterface can get a bit quirky, an effective library can abstract away most of the quirks and provide a convenient API allowing you to take advantage of Flash’s improved file-handling abilities through JavaScript.

Building an effective upload UI

On Flickr, we implemented a simple large “Choose photos and videos” link which when clicked, opens a multi-select-capable file-selection dialog driven by the YUI Uploader (which requires Flash 9). YUI Uploader provides file metadata via fileSelect event callbacks after files are selected, at which point the file list and UI can be updated. The user can add and remove files as they like according to business logic, configure upload options and so on.

Beginning the Upload

Once the user has prepared their selection of files and clicked “Upload Photos and Videos”, the file queue is processed. YUI Uploader can upload files simultaneously or in sequence to a given URL (a signed API call in Flickr’s case) with callbacks for file progress, errors, file completion and upload completion. The idea is that the control’s Flash component simply sends files and reports errors and progress, leaving all of the event handling to JavaScript. Because of this separation, upload behaviours can easily be changed or updated without having to change the Flash component.

Upload Progress

During file upload, the uploadProgress event fires regularly, providing the file ID, bytes uploaded and total bytes for each file. This data can be reflected as a progress bar, a percentage value or raw bytes depending on your UI.





Flickr Uploadr screencast from designingwebinterfaces on Flickr.

Connection Error Handling

If a file upload fails due to a connection or IO error from Flash, the uploadError event will fire so you can attempt to gracefully recover by retrying the upload of that file. Another safeguard is to implement a basic timeout such that if a file upload “hangs” for too long without a reported error (e.g., 2 minutes passes without an uploadProgress event), the file upload can be aborted.

File Upload Response Handling

When a file has been posted to the target URL, the server response is passed to a JavaScript callback via the uploadCompleteData event. Photos are processed asynchronously post-upload in Flickr’s case, so a processing ticket ID is provided in the upload response. The ticket ID is then polled via API calls until a success/fail result is ultimately returned after server-side processing.

Uploader Start-Up Handling

YUI Uploader handles the creation and writing out of the Flash object and its initialization process. Once the control has loaded, the contentReady event fires and the file selection process can begin. It is worth considering displaying some sort of “loading” element in your UI, in case the user wants to “choose files” before the control has initialized. In Flickr’s case, we show a small animation next to the “Choose photos and videos” link to indicate a loading state, as well as greying out the text itself.

It is also helpful to have a fall-through error handler that redirects the user to an alternate upload method, such as a non-JavaScript form-based file upload. The Flickr Uploadr detects for Flash 9+ upfront with JavaScript (e.g., the SWFObject), and also uses a try...catch block in the init method and around the file-selection bits. So if something goes wrong during initialization or when the user clicks the “Choose” link, exceptions trigger a fall-through to our basic uploader. This also is an appropriate fallback for users who don’t have Flash or JavaScript to begin with.

Special Casing: Handling Flash 10 Security Restrictions

Due to a change in the security model beginning with Flash 10, file selection must now begin via the user clicking directly on the Flash movie. With previous versions, you could call [Flash movie].selectFiles() from JavaScript and the selection dialog would be shown without requiring user action.

To keep the user experience consistent on Flickr where an HTML link could trigger the selection dialog, we made the Flash movie transparent and overlaid it on top of the HTML link. Thus, the Flash movie captures the click and the selection dialog works as expected. One might call this a legitimate, local form of clickjacking.

If repositioning the Flash movie is undesirable in your use case, another option is to render the link, text or button UI within the Flash movie itself and show the movie as a normal inline element.

Should I Use This?

While there are some notable technical considerations associated with developing a Flash-based uploader UI — such as initialization and error handling — as with most nifty/shiny web things, the technical complexity of the implementation rests solely with the developer. Once the application logic has been implemented by the developer and integrated with YUI Uploader, the end result is an upload experience that is consistently faster, more convenient, efficient and more robust to the end user.

14 Comments

  1. What would make this really flexible would be support for drag and drop file selection. Is Flash is able to support that? I assume it must not be, or you would have already implemented it.

  2. Flash does not currently allow dragging and dropping of files from the desktop, to the best of my knowledge. This may be difficult to do cross-platform, but I also suspect it may not be implemented because of security restrictions between the OS, browser and Flash plugin. Thus, the method of selecting files is via a standard OS dialog.
    Adobe’s AIR technology does allow for drag-and-drop file support (as far as I’m aware), but it is more of a desktop-oriented product.

  3. BrowserPlus has a similar upload tool and supports drag and drop file selection (as well as desktop notifications and much, much more). Check it out here:

    http://browserplus.yahoo.com/developer/web/toolbox/upload/

  4. Hi,

    I’m using YUI a lot, and also at http://www.uploadforme.com, a service to help people import larqe quantities of data in multiple online services.

    I wanted to use the YUI uploader, but it’s of no use under Linux: no progress bar update and the browser’s UI blocked during transfer (I’m using firefox). I’ve been told this is a flash problem, which I tend to believe as other flash uploaders (like swfupload) have the same problem. As blocking the whole browser is worse than one-file-at-a-time-uploads, I’ve postponed the use of flash uploaders.

    Raphaël

  5. The problem with BrowserPlus (fine as it is) is that it doesn’t support enough browsers (p.e. Opera is missing); the Flickr Uploader has to be a lot more generalistic one if just because the sheer number of different user environments where it has to run.

  6. Raphael,

    I haven’t heard of Flash blocking the browser UI while uploading files under Ubuntu, but perhaps it’s more specific to the version/variant of Linux you’re using (which flavour, specifically?)

  7. Raphael & Scott,
    This is a known issue in linux: http://bugs.adobe.com/jira/browse/FP-377

    Not yet resolved.

  8. You also have Java applets solutions because the Java runtime is installed on many computers. You can a Flickr upload applet on JFileUpload web site. You can preview images, rotate before upload, even scale images.

  9. Fizzle Masterson said:
    March 2, 2009 at 2:11 pm

    Smugmug.com uses YUI components (last time I checked), and they use a drag-n-drop interface. They use Java for their primary uploader.

  10. Yo Luis,

    I have the cards of 4 folks inside opera sittin’ on my desk, and both opera support and linux/unix support are extremely interesting next steps for BrowserPlus. Our push yesterday includes support for 11 languages, and the installation experience is much better, with plans to make it absolutely seemless in our next drop later this month. Hopefully this focus demonstrates our understanding of the key arguments against employing browserplus.

    That said, I think it’s universally understood that a fallback experience is required whenever you employ a non-browser client side technology, java, flash, gears, or browserplus. Any of these technologies gives you 90%+ coverage of desktop client environments. (Raphaël raising a key representative issue why there always must be a fallback).

    Given that you can benefit 90% of your audience, and given the ease with which your end users can install browserplus, (see for yourself: http://browserplus.yahoo.com/demos/profile – no browser restart required, not even a refresh – this is not true for java nor flash nor gears)…

    …dontcha think the decision should be based on what delivers the best user experience, features, and implementation & maintenence cost?

    as far as I’ve heard, folks choose flash because of it’s maturity and the purported 97% installed base… if you’re content with the features flash provides, then it’s pretty much game over. But if you wanna write your interface in 100% open web technologies and want support for things like desktop sourced drag and drop… *and* you want the ability to add and effect core features of the platform you choose, perhaps the conversation is just starting?

    very best,
    lloyd

  11. For those who are interested, the linux-specific UI blocking bug has been updated by Adobe:
    http://bugs.adobe.com/jira/browse/FP-377

    Supposedly fixed for the new major release. They haven’t specified when exactly though.

  12. our application is accessed via a SSO (single sign on) solution, which requires the YUI Uploader to use the same session as the browser. Is the a way to accomplish this ?

  13. Well i was convinced to use YUI after reading your post and now i had something that is quite working in IE but in firefox or opera, it seems the session is lost when getting to the upload script.

    and i don’t find any solution working ( i tried to pass the session id to the script already) :(

  14. @david — The best way to get help on YUI components is to post a question on our community forums:

    http://yuilibrary.com/forum/viewforum.php?f=89

    -Eric