Tutorials Books Videos Forums

-- online Change the theme! Search!
Rambo ftw!

Customize Theme


Color

Background


Done

Uploading Files using FileReference

by Kyle Murray aka Krilnon   | filed under Flash and ActionScript

This is an archived tutorial from the kirupa.com legacy collection. It covers software that may no longer be available, but it is kept online because the ideas still hold up.

The ability to upload files to a server from Flash was one of the most requested features added in Flash 8. Flash implements this ability through the FileReference class. This tutorial will serve as an introduction to the uploading features of the class and hopefully the example provided will help you on your way towards building your own upload-capable application!

The FileReference class allows Flash to open the familiar file selection dialog box that displays a list of files found on a user's file system. Once a file has been selected, Flash can then begin to upload the file to a remote server. FileReference also provides Flash with some information regarding the file that may be useful to you as a developer. For example, the name, size, and file type/extension can all be accessed through FileReference properties.

Note:

There are a few points regarding FileReference that continue to come up in the forums. One important thing to keep in mind is that Flash will never know the location of the file on the user's computer. If a file 'file:///C:/Kirupa/image.jpg' was selected using FileReference's browse method, Flash would only know that the file was named 'image.jpg'. Second, some sort of server-side upload script is needed to successfully upload a file. Flash alone cannot upload a file to a server, even with FileReference.

Below is an image of what you will have produced by the end of this tutorial. You can test out a complete version using the source files given throughout this tutorial and a server of your own.

[ a screenshot of the uploader in action ]

Let's Begin:

Download the full Flash source for this tutorial now. Don't worry, the important part of this tutorial, the ActionScript, will be covered in detail later. The .fla file contains two buttons for user input and a TextField to keep the user informed. An example server-side script will be provided later on.

Once you've opened the document, navigate to the 'Actions' layer on the first frame, make sure that the Actions panel is visible. In the next section, we'll break down the source code and examine it line-by-line.

The functions from the file in the previous section are defined alphabetically, but the ActionScript will be explained in the order that the functions are called. Error handling will be dealt with closer to the end. Keep in mind that a few identifiers are defined in the .fla itself and not in the ActionScript, namely the two buttons (uploadButton_mc and chooseButton_mc) and the TextField (display_txt).

On to the ActionScript:

import flash.net.FileReference;
var progressBar:MovieClip;
var reference:FileReference = new FileReference();
var referenceListener:Object = {};
var scriptLocation:String = 'uploader.php';
var progressBarHeight:Number = 10;
var progressBarY:Number = 50;
var progressBarColor:Number = 0x66ccff;
uploadButton_mc._visible = false;
reference.addListener(referenceListener);
referenceListener.onSelect = activateUploadButton;
referenceListener.onProgress = updateProgress;
referenceListener.onComplete = restart;
referenceListener.onHTTPError = handleError;
referenceListener.onIOError = handleError;
referenceListener.onSecurityError = handleError;
chooseButton_mc.onRelease = choose;
uploadButton_mc.onRelease = uploadCurrent;

In this section, we are setting up for what is to come. The progress bar doesn't exist yet, but multiple functions will need to access it once it is instantiated, so the identifier is defined in a scope accessible to the functions we will create. Unlike MovieClips, FileReference instances don't handle the process of listening and handling events alone, so a generic object is created to listen for FileReference-related events. The same FileReference object will be used by multiple uploads, should the user choose to upload more than one file. The browse method writes over the properties of its FileReference object each time a file is selected, so we don't have to worry about an old upload contaminating the next.

The next four lines define implementation-specific details that would probably be different for each uploader application. In the next line, the 'Upload' button is hidden from the user until he chooses a file to upload. After that, we tell the object we created earlier to listen for events generated by our FileReference instance. The next lines set a number of functions to be triggered when a FileReference event is generated. The second to last line sets a function to be called when the 'Choose' button is pressed.

You might have noticed that the rest of the ActionScript consists of a bunch of function definitions. That means that there must be something in the above lines of code that will start a chain of function calls to upload a file! It turns out the the onRelease handler we just defined will have to start the chain, since none of the FileReference events will be generated until the browse method is called, and that method isn't called until the 'Choose' button is pressed. Let's examine the handler, choose, now.

function choose():Void {
  reference.browse([{description:'All Files (*.*)', extension:'*.*'}]);
}

At first glance, this function looks fairly simple. It turns out that the browse method accepts somewhat complex input, since the input determines which file types a user can upload. The only (explicit) parameter that this method accepts is an Array. Each element in the array represents a file type group, such as 'Images' or 'Videos'. Elements must be of the Object type (so it is convenient to use the Object literal braces '{}'), and each Object needs to have at least two properties: 'description' and 'extension'. An optional 'macType' property can be specified so that OSX users can have their files filtered by a special file property. In this tutorial, any file type can be uploaded, signified by the wildcard (*) characters on either side of the period in the 'extension' field's contents.

It is important that you allow only the file types that you need your user to be able to upload in order for your application to function properly. Allowing extraneous file types wastes bandwidth and potentially malicious attacks. File size is another issue that can be addressed while still in Flash. If you wish to limit user upload file size, check the size of the selected file using the size property after the user has selected a file, when the onSelect handler is called. Recall that our handler is the activateUploadButton function.

In the next section, we'll see how this function works, and continue to explore the ActionScript.

ActionScript Explanation Continued:

The body of the button activation function mentioned in the previous section is as follows:

function activateUploadButton():Void {
  display_txt.text = reference.name;
  uploadButton_mc._visible = true;
}

Once the user has selected a file, we place the name of the file in our TextField. This way, the user is certain that she has selected the correct file. We then activate the 'Upload' button, since unless the user has made a selection mistake, he is now ready to upload the file. When the button is released, we begin to upload the file using uploadCurrent.

function uploadCurrent():Void {
  chooseButton_mc._visible = false;
  progressBar = makeProgressBar(0, progressBarY);
  reference.upload(scriptLocation);
}

Now that the user has chosen a file to upload, she no longer needs the 'Choose' button, so we hide it for now. Progress bars are a fairly standard way to inform users of how far along an operation is, and we create the MovieClip to contain ours now. The makeProgressBar function simply draws a box and sets its width to 0. The ActionScript explanation is not included here, but is covered in the Drawing API tutorial by pom. The bar is deleted and created again each upload to avoid having a MovieClip in memory when it isn't needed. The final line tells the FileReference to attempt to start the upload. For now, we are at the mercy of our upload script.

[ a simple example uploader script in PHP ]

Periodically, Flash will be notified of updates in the progress of the upload. When that happens, Flash notifies the FileReference, which will call the function assigned to be onProgress handler. In our case, that handler is updateProgress:

function updateProgress(fileReference:FileReference, bytesLoaded:Number, bytesTotal:Number):Void {
  display_txt.text = fileReference.name+' - '+Math.ceil((bytesLoaded/bytesTotal)*100)+'%';
  progressBar._width = Math.ceil(Stage.width*(bytesLoaded/bytesTotal));
}

The progress event comes with two familiar pieces of data about the progress that you are probably familiar with already if you have dealt with loading in Flash before, bytesLoaded and bytesTotal. The width of the progress bar is set to some fraction (representing load progress) of the width of the Stage, and the TextField displays a rounded percentage.

function restart():Void {
  removeMovieClip(progressBar);
  display_txt.text = '';
  uploadButton_mc._visible = false;
  chooseButton_mc._visible = true;
}

When the upload (finally) finishes, Flash dispatches an event and, in our case, the restart function is called. This functions prepares the application for another file upload. To accomplish this, we remove the progress bar, clear the TextField, and set the buttons back to their default states. The user now has the option of uploading another file, and the process should repeat itself smoothly.

In the next section, we'll implement error handling and discuss solutions for common problems.

Errors and Error Handling:

We now need to deal with errors that may be generated from the application we were coding in the previous section. Since this application depends largely on a remote server, errors are somewhat harder to predict. Thankfully, most of them can be dealt with, and Flash can report what sorts of errors are occurring.

One of the more common errors is a permission error. Your server may allow an upload, but the script that you used to upload the file may not have permission to store that file in a directory on the server. Unfortunately, this sort of error isn't passed on to Flash, so test your upload script thoroughly before deploying it anywhere. Using Apache, this sort of error can be solved by changing the chmod of the folder to allow 'Other' the permission to write (I used 757). Similar permission settings can be changed using on a Windows server through IIS.

Note:

A little over a year ago, the previous change was the only one that I had to make. Several server configuration changes later, I noticed that file uploads weren't working any longer. Thanks to a note on the Adobe LiveDocs, I was able to fix the issue by adding the following lines to my .htaccess file:

SecFilterEngine Off
SecFilterScanPOST Off

Beware, the completion event fires before this error is thrown, so be sure that your code can handle such an error.

The error handling in this tutorial is contained within a single function. It would be possible to handle each of the three types of errors separately, but the error response in this case will be so similar for each type that they group logically into one function:

function handleError(errorName:String, detail:Object):Void {
  restart();
  if (arguments.length === 2) {
  if (typeof detail === 'number') {
  display_txt.text = 'HTTP Error #'+detail;
  } else {
  display_txt.text = 'Security Error: '+detail;
  }
  } else {
  display_txt.text = 'IO Error';
  }
}

The application resets itself when an error occurs, just as it did when it completed successfully. This way, the user can try again and hopefully avoid the error. The conditional statements following the restart check the type of error. Conveniently, the three kinds of errors all pass slightly different arguments into the handler. An IOError only passes one argument, so it is easily identified by checking the length of the arguments array accessible from every function. HTTP and IO errors both pass two arguments, but an HTTPError passes the second argument as a Number, not a String. This difference can be detected using the typeof operator. In any case, the application simply passes along all of the information it is given to the user.

Wrap Up:

Hopefully this tutorial has served as a useful introduction to the upload features of the FileReference class. As always, the kForums are available for questions, and I always try to respond to my PMs (though the forums are usually a more effective means of getting help).

Krilnon
Reclipse

Just a final word before we wrap up. What you've seen here is freshly baked content without added preservatives, artificial intelligence, ads, and algorithm-driven doodads. A huge thank you to all of you who buy kirupa's books, became a paid subscriber, watch the videos, and/or interact on the forums.

Your support keeps this site going! 😇

The KIRUPA Newsletter

Thought provoking content that lives at the intersection of design 🎨, development 🤖, and business 💰 - delivered weekly to over a bazillion subscribers!

SUBSCRIBE NOW

Creating engaging and entertaining content for designers and developers since 1998.

Follow:

Popular

Loose Ends

:: Copyright KIRUPA 2026 //--