DojoX FileUploader Upgrade to Support Flash 10 December 1st, 2008 at 2:00 pm by Mike Wilcox

I’ve just completed the upgrade of the DojoX FileUploader to make it compatible with Flash Player 10. The FileUploader widget allows for the uploading of more than one file at a time, which is surprisingly still not supported natively by any web browser on the market today.

In Flash versions 8 and 9, a file upload Browse Dialog could be launched using JavaScript code. Users could click an HTML button, which would call a JavaScript function behind the scenes, communicate with a Flash (SWF) file, which would then trigger the browse() method in the SWF. The latest Flash Player has a security feature where the user must click within a Flash-based portion of the user interface to launch the Browse Dialog. This change is to prevent malicious code from continually opening the dialog without user interaction. Working toward this upgrade was a major undertaking that involved a significant rewrite of FileUploader. The results are a success, and in addition to working with the tightened security policies, it was a great opportunity to add many new features:

  • Degradable
  • CDN Support (see below for cross-domain restriction details)
  • POST Data Support
  • Custom Field Name Support
  • Full Event Support
  • Exposed CSS Positioning
  • Dialog Container Detection

Degradable

As it worked before, the FileUploader detects if the browser has the Flash plugin version 9.0 or greater installed, and if so, initializes the Flash FileUploader. If not, a conventional fileInput is used. You can always set the force parameter to either “flash” or “html” to require a particular version of the FileUploader and override the detection. By default, force is an empty string, triggering the detection.

CDN Support

Dojo’s CDN is very important system for the Open Web, but occasionally there are issues since the JavaScript is being served from a different domain than the page launching the code. This is compounded by security restrictions within Flash. The FileUploader embed code now contains the proper parameters to enable communication and execution between the FileUploader SWF and JavaScript belonging to different domains:

allownetworking="all"
allowscriptaccess ="always"

However, there are still limitations to what can be done over the CDN. The SWF must be from the same domain as the HTML page - it will currently not work with the SWF on the CDN server. We’re still investigating possible solutions for serving the FileUploader SWF from the CDN. In the meantime, the swfPath parameter has been exposed so that you may link to a local SWF, which of course could be the same SWF downloaded from the dojox/form/resource folder.

POST Data Support

You can now pass in POST data that will be posted to the server along with the Flash uploaded files. Previously, this could be done by appending variables to the URL, but that was unreliable. I’ve tapped into the Flash feature that appends the data for you:

//ActionScript
request = new URLRequest(uploadUrl);
request.method = URLRequestMethod.POST;
request.data = getPostData();

Additionally, if the HTML FileUploader is used, the postData object will be converted into hidden fields and posted to the server.

Custom Field Name Support

You can now specify the field name that the server expects to find the files. Flash defaults to using the Filedata field name for the files, which is fine if you are customizing the server or building it from scratch. But naturally, some systems are already in place and such a change may not be desirable. Simply set the flashFieldName parameter, and that’s what will be sent. The htmlFieldName is used for the HTML version of the FileUploader.

Full Event Support

I went to great lengths to expose as many events as possible. All the mouse actions have event methods that can be connected to, since they are already used for emulating the hover state of the ‘fake’ button — the styled button that acts as the stand-in for the actual upload button. The canceling of the dialog window is captured in Flash, and passed to a method in the FileUploader. In order to mirror that functionality with the HTML FileUploader, I noticed that the onMouseOut() event of the fileInput does not fire until the dialog is closed. By checking that a file was not selected, I can create a pseudo cancel event and pass that to the onCancel() method.

Exposed CSS Positioning

Now that the Flash FileUploader has to use the same CSS hacks as the HTML FileUploader, it was more important than ever to get the positioning right. It’s been tweaked and massaged, and I have it working for several different use cases. However, because of the nature of this “hack”—floating a zero-opacity fileInput or a transparent SWF over a “fake” button—this won’t work in all circumstances. For instance, the uploaders won’t work properly in a scrolling div. CSS rules can unexpectedly cause placement issues. Placing the FileUploader near the bottom of a complex document can throw off the positioning. The positioning methods have been exposed for overriding in these cases. The setPosition() method can be called whenever there has been a screen redraw that may upset the placement. For certain cases not covered, it’s just a matter of replacing the setFlashPosition() and/or the setHtmlPostion() and using your own code.

Dialog Container Detection

In my experience, a very common use case for the FileUploader is within a Dijit Dialog. I’ve written a script that walks up the DOM tree and checks if the ‘fake’ button is a child of a Dialog. If so, the show() and hide() methods of the Dialog are connected to—since we don’t want an invisible Upload button floating around our document. The dragging of the Dialog box also triggers the setPosition() to keep it in place.

Summary

File uploads are common on the web, but browsers still provide a poor user experience for multiple-file uploads. The SitePen and Dojo teams are striving to make it as easy as possible to implement a great experience for your users. The new DojoX FileUploader will be available in the forthcoming Dojo 1.3 release, any Dojo nightly build, or from Dojo’s Subversion repository. Please send us your feedback and feature requests, or if you need assistance implementing this within your application, check out our support and development services.

Tags: ,

8 Responses to “DojoX FileUploader Upgrade to Support Flash 10”

  1. Pete says:

    Mike, is it possible to use flash.html.HtmlControl to render the “fake” button, the host page could pass it in? Would it avoid some of the layout problems?

  2. mwilcox says:

    That’s an intriguing idea and would be quite a morph of the two technologies (which I’m interested in). But in this case it wouldn’t help, as we still have to rely upon the browser to tell us what the x/y coordinate is of the button, or the placement of the object rendered in this case.

  3. Franz says:

    Uh oh, I’ve just run into a major problem in my use of FileUploader: Flash doesn’t seem to be sending cookies, so I can’t authenticate the upload request! I’m using a Java servlet, and I need the jsessionid cookie to identify the logged-in user. Is there a switch you can set to make it send cookies?

  4. Franz says:

    Oops, another problem, though much less serious: the Flash uploader silently ignores zero-length files. I was baffled as to why some files weren’t uploading until I noticed their sizes. This is likely to confuse users, too.

  5. ben says:

    hey, i was just in the middle of coding the same thing - so glad to see you’ve already done it.

    was also just running into the session ID issue today. haven’t implemented yet, but am planning to output the session ID as a param sent to flash - and then have flash send the ID back to server as a POST var. then will have to do a slight mod on the server to have it tell php that that var is the session id.

    here’s a relevant post:
    http://bytes.com/groups/php/525560-flash-php-session

  6. mwilcox says:

    The uploader not sending cookies is a Flash bug:
    http://bugs.adobe.com/jira/browse/FP-201

    Headers can be sent in an UrlRequest Header, but I don’t know if it would work around your problem, as it is very restricted. The way I had done it in the past is to get the user and session IDs and pass those as vars along with the upload. That’s why I implemented the postVars in the latest version.

    Zero-length is also a Flash issue:
    http://bugs.adobe.com/jira/browse/FP-510
    You could possibly catch that one as you select the file in the onChange handler.

  7. Franz says:

    It looks like the new FileUploader isn’t part of Dojo 1.2.3, since I’m getting errors with Flash 10, and I can’t find any mention of postVars in the source. Is it scheduled for Dojo 1.3?

  8. mwilcox says:

    Sorry, I don’t think I mentioned that. Yes, it’s checked in and scheduled for Dojo 1.3. It’s currently available in the nightlies and svn.

Leave a Reply