📄 swfupload.as
字号:
package {
/*
* Todo:
* I should look in to using array.splice to remove cancelled files from the array.
* Add GetFile(file_id) function that returns the FileItem js object for any file (defaults to current or first in queue).
* */
import flash.display.Stage;
import flash.display.Sprite;
import flash.net.FileReferenceList;
import flash.net.FileReference;
import flash.net.FileFilter;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
import flash.events.*;
import flash.external.ExternalInterface;
import flash.system.Security;
import FileItem;
import ExternalCall;
public class SWFUpload extends Sprite {
// Cause SWFUpload to start as soon as the movie starts
public static function main():void
{
var SWFUpload:SWFUpload = new SWFUpload();
}
private const build_number:String = "SWFUPLOAD 2.1.0 FP9 2008-03-12";
// State tracking variables
private var fileBrowserMany:FileReferenceList = new FileReferenceList();
private var fileBrowserOne:FileReference = null; // This isn't set because it can't be reused like the FileReferenceList. It gets setup in the SelectFile method
private var file_queue:Array = new Array(); // holds a list of all items that are to be uploaded.
private var current_file_item:FileItem = null; // the item that is currently being uploaded.
private var file_index:Array = new Array();
private var successful_uploads:Number = 0; // Tracks the uploads that have been completed
private var queue_errors:Number = 0; // Tracks files rejected during queueing
private var upload_errors:Number = 0; // Tracks files that fail upload
private var upload_cancelled:Number = 0; // Tracks number of cancelled files
private var queued_uploads:Number = 0; // Tracks the FileItems that are waiting to be uploaded.
private var valid_file_extensions:Array = new Array();// Holds the parsed valid extensions.
// Callbacks
private var flashReady_Callback:String;
private var fileDialogStart_Callback:String;
private var fileQueued_Callback:String;
private var fileQueueError_Callback:String;
private var fileDialogComplete_Callback:String;
private var uploadStart_Callback:String;
private var uploadProgress_Callback:String;
private var uploadError_Callback:String;
private var uploadSuccess_Callback:String;
private var uploadComplete_Callback:String;
private var debug_Callback:String;
// Values passed in from the HTML
private var movieName:String;
private var uploadURL:String;
private var filePostName:String;
private var uploadPostObject:Object;
private var fileTypes:String;
private var fileTypesDescription:String;
private var fileSizeLimit:Number;
private var fileUploadLimit:Number = 0;
private var fileQueueLimit:Number = 0;
private var useQueryString:Boolean = false;
private var requeueOnError:Boolean = false;
private var debugEnabled:Boolean;
private var credentials_name:String = "";
private var credentials_password:String = "";
// Error code "constants"
// Size check constants
private var SIZE_TOO_BIG:Number = 1;
private var SIZE_ZERO_BYTE:Number = -1;
private var SIZE_OK:Number = 0;
// Queue errors
private var ERROR_CODE_QUEUE_LIMIT_EXCEEDED:Number = -100;
private var ERROR_CODE_FILE_EXCEEDS_SIZE_LIMIT:Number = -110;
private var ERROR_CODE_ZERO_BYTE_FILE:Number = -120;
private var ERROR_CODE_INVALID_FILETYPE:Number = -130;
// Upload Errors
private var ERROR_CODE_HTTP_ERROR:Number = -200;
private var ERROR_CODE_MISSING_UPLOAD_URL:Number = -210;
private var ERROR_CODE_IO_ERROR:Number = -220;
private var ERROR_CODE_SECURITY_ERROR:Number = -230;
private var ERROR_CODE_UPLOAD_LIMIT_EXCEEDED:Number = -240;
private var ERROR_CODE_UPLOAD_FAILED:Number = -250;
private var ERROR_CODE_SPECIFIED_FILE_ID_NOT_FOUND:Number = -260;
private var ERROR_CODE_FILE_VALIDATION_FAILED:Number = -270;
private var ERROR_CODE_FILE_CANCELLED:Number = -280;
private var ERROR_CODE_UPLOAD_STOPPED:Number = -290;
public function SWFUpload() {
// Do the feature detection. Make sure this version of Flash supports the features we need. If not
// abort initialization.
if (!flash.net.FileReferenceList || !flash.net.FileReference || !flash.net.URLRequest || !flash.external.ExternalInterface || !flash.external.ExternalInterface.available || !DataEvent.UPLOAD_COMPLETE_DATA) {
return;
}
Security.allowDomain("*"); // Allow uploading to any domain
// Keep Flash Player busy so it doesn't show the "flash script is running slowly" error
var counter:Number = 0;
root.addEventListener(Event.ENTER_FRAME, function ():void { if (++counter > 100) counter = 100; });
// Setup file FileReferenceList events
this.fileBrowserMany.addEventListener(Event.SELECT, this.Select_Many_Handler);
this.fileBrowserMany.addEventListener(Event.CANCEL, this.DialogCancelled_Handler);
// Get the move name
this.movieName = root.loaderInfo.parameters.movieName;
// **Configure the callbacks**
// The JavaScript tracks all the instances of SWFUpload on a page. We can access the instance
// associated with this SWF file using the movieName. Each callback is accessible by making
// a call directly to it on our instance. There is no error handling for undefined callback functions.
// A developer would have to deliberately remove the default functions,set the variable to null, or remove
// it from the init function.
this.flashReady_Callback = "SWFUpload.instances[\"" + this.movieName + "\"].flashReady";
this.fileDialogStart_Callback = "SWFUpload.instances[\"" + this.movieName + "\"].fileDialogStart";
this.fileQueued_Callback = "SWFUpload.instances[\"" + this.movieName + "\"].fileQueued";
this.fileQueueError_Callback = "SWFUpload.instances[\"" + this.movieName + "\"].fileQueueError";
this.fileDialogComplete_Callback = "SWFUpload.instances[\"" + this.movieName + "\"].fileDialogComplete";
this.uploadStart_Callback = "SWFUpload.instances[\"" + this.movieName + "\"].uploadStart";
this.uploadProgress_Callback = "SWFUpload.instances[\"" + this.movieName + "\"].uploadProgress";
this.uploadError_Callback = "SWFUpload.instances[\"" + this.movieName + "\"].uploadError";
this.uploadSuccess_Callback = "SWFUpload.instances[\"" + this.movieName + "\"].uploadSuccess";
this.uploadComplete_Callback = "SWFUpload.instances[\"" + this.movieName + "\"].uploadComplete";
this.debug_Callback = "SWFUpload.instances[\"" + this.movieName + "\"].debug";
// Get the Flash Vars
this.uploadURL = root.loaderInfo.parameters.uploadURL;
this.filePostName = root.loaderInfo.parameters.filePostName;
this.fileTypes = root.loaderInfo.parameters.fileTypes;
this.fileTypesDescription = root.loaderInfo.parameters.fileTypesDescription + " (" + this.fileTypes + ")";
this.loadPostParams(root.loaderInfo.parameters.params);
if (!this.filePostName) {
this.filePostName = "Filedata";
}
if (!this.fileTypes) {
this.fileTypes = "*.*";
}
if (!this.fileTypesDescription) {
this.fileTypesDescription = "All Files";
}
this.LoadFileExensions(this.fileTypes);
try {
this.debugEnabled = root.loaderInfo.parameters.debugEnabled == "true" ? true : false;
} catch (ex:Object) {
this.debugEnabled = false;
}
try {
this.SetFileSizeLimit(String(root.loaderInfo.parameters.fileSizeLimit));
} catch (ex:Object) {
this.fileSizeLimit = 0;
}
try {
this.fileUploadLimit = Number(root.loaderInfo.parameters.fileUploadLimit);
if (this.fileUploadLimit < 0) this.fileUploadLimit = 0;
} catch (ex:Object) {
this.fileUploadLimit = 0;
}
try {
this.fileQueueLimit = Number(root.loaderInfo.parameters.fileQueueLimit);
if (this.fileQueueLimit < 0) this.fileQueueLimit = 0;
} catch (ex:Object) {
this.fileQueueLimit = 0;
}
// Set the queue limit to match the upload limit when the queue limit is bigger than the upload limit
if (this.fileQueueLimit > this.fileUploadLimit && this.fileUploadLimit != 0) this.fileQueueLimit = this.fileUploadLimit;
// The the queue limit is unlimited and the upload limit is not then set the queue limit to the upload limit
if (this.fileQueueLimit == 0 && this.fileUploadLimit != 0) this.fileQueueLimit = this.fileUploadLimit;
try {
this.useQueryString = root.loaderInfo.parameters.useQueryString == "true" ? true : false;
} catch (ex:Object) {
this.useQueryString = false;
}
try {
this.requeueOnError = root.loaderInfo.parameters.requeueOnError == "true" ? true : false;
} catch (ex:Object) {
this.requeueOnError = false;
}
try {
ExternalInterface.addCallback("SelectFile", this.SelectFile);
ExternalInterface.addCallback("SelectFiles", this.SelectFiles);
ExternalInterface.addCallback("StartUpload", this.StartUpload);
ExternalInterface.addCallback("ReturnUploadStart", this.ReturnUploadStart);
ExternalInterface.addCallback("StopUpload", this.StopUpload);
ExternalInterface.addCallback("CancelUpload", this.CancelUpload);
ExternalInterface.addCallback("GetStats", this.GetStats);
ExternalInterface.addCallback("SetStats", this.SetStats);
ExternalInterface.addCallback("GetFile", this.GetFile);
ExternalInterface.addCallback("GetFileByIndex", this.GetFileByIndex);
//ExternalInterface.addCallback("SetCredentials", this.SetCredentials); // Will be introduced with the Flex 3 SDK
ExternalInterface.addCallback("AddFileParam", this.AddFileParam);
ExternalInterface.addCallback("RemoveFileParam", this.RemoveFileParam);
ExternalInterface.addCallback("SetUploadURL", this.SetUploadURL);
ExternalInterface.addCallback("SetPostParams", this.SetPostParams);
ExternalInterface.addCallback("SetFileTypes", this.SetFileTypes);
ExternalInterface.addCallback("SetFileSizeLimit", this.SetFileSizeLimit);
ExternalInterface.addCallback("SetFileUploadLimit", this.SetFileUploadLimit);
ExternalInterface.addCallback("SetFileQueueLimit", this.SetFileQueueLimit);
ExternalInterface.addCallback("SetFilePostName", this.SetFilePostName);
ExternalInterface.addCallback("SetUseQueryString", this.SetUseQueryString);
ExternalInterface.addCallback("SetRequeueOnError", this.SetRequeueOnError);
ExternalInterface.addCallback("SetDebugEnabled", this.SetDebugEnabled);
} catch (ex:Error) {
this.Debug("Callbacks where not set.");
return;
}
this.Debug("SWFUpload Init Complete");
this.PrintDebugInfo();
ExternalCall.Simple(this.flashReady_Callback);
}
/* *****************************************
* FileReference Event Handlers
* *************************************** */
private function DialogCancelled_Handler(event:Event):void {
this.Debug("Event: fileDialogComplete: File Dialog window cancelled.");
ExternalCall.FileDialogComplete(this.fileDialogComplete_Callback, 0, 0);
}
private function Open_Handler(event:Event):void {
this.Debug("Event: uploadProgress (OPEN): File ID: " + this.current_file_item.id);
ExternalCall.UploadProgress(this.uploadProgress_Callback, this.current_file_item.ToJavaScriptObject(), 0, this.current_file_item.file_reference.size);
}
private function FileProgress_Handler(event:ProgressEvent):void {
this.Debug("Event: uploadProgress: File ID: " + this.current_file_item.id + ". Bytes: " + event.bytesLoaded + ". Total: " + event.bytesTotal);
ExternalCall.UploadProgress(this.uploadProgress_Callback, this.current_file_item.ToJavaScriptObject(), event.bytesLoaded, event.bytesTotal);
}
private function ServerData_Handler(event:DataEvent):void {
this.successful_uploads++;
this.current_file_item.file_status = FileItem.FILE_STATUS_SUCCESS;
this.Debug("Event: uploadSuccess: File ID: " + this.current_file_item.id + " Data: " + event.data);
ExternalCall.UploadSuccess(this.uploadSuccess_Callback, this.current_file_item.ToJavaScriptObject(), event.data);
this.UploadComplete(false);
}
private function HTTPError_Handler(event:HTTPStatusEvent):void {
this.upload_errors++;
this.current_file_item.file_status = FileItem.FILE_STATUS_ERROR;
this.Debug("Event: uploadError: HTTP ERROR : File ID: " + this.current_file_item.id + ". HTTP Status: " + event.status + ".");
ExternalCall.UploadError(this.uploadError_Callback, this.ERROR_CODE_HTTP_ERROR, this.current_file_item.ToJavaScriptObject(), event.status.toString());
this.UploadComplete(true); // An IO Error is also called so we don't want to complete the upload yet.
}
// Note: Flash Player does not support Uploads that require authentication. Attempting this will trigger an
// IO Error or it will prompt for a username and password and may crash the browser (FireFox/Opera)
private function IOError_Handler(event:IOErrorEvent):void {
// Only trigger an IO Error event if we haven't already done an HTTP error
if (this.current_file_item.file_status != FileItem.FILE_STATUS_ERROR) {
this.upload_errors++;
this.current_file_item.file_status = FileItem.FILE_STATUS_ERROR;
this.Debug("Event: uploadError : IO Error : File ID: " + this.current_file_item.id + ". IO Error: " + event.text);
ExternalCall.UploadError(this.uploadError_Callback, this.ERROR_CODE_IO_ERROR, this.current_file_item.ToJavaScriptObject(), event.text);
}
this.UploadComplete(true);
}
private function SecurityError_Handler(event:SecurityErrorEvent):void {
this.upload_errors++;
this.current_file_item.file_status = FileItem.FILE_STATUS_ERROR;
this.Debug("Event: uploadError : Security Error : File Number: " + this.current_file_item.id + ". Error text: " + event.text);
ExternalCall.UploadError(this.uploadError_Callback, this.ERROR_CODE_SECURITY_ERROR, this.current_file_item.ToJavaScriptObject(), event.text);
this.UploadComplete(true);
}
private function Select_Many_Handler(event:Event):void {
this.Select_Handler(this.fileBrowserMany.fileList);
}
private function Select_One_Handler(event:Event):void {
var fileArray:Array = new Array(1);
fileArray[0] = this.fileBrowserOne;
this.Select_Handler(fileArray);
}
private function Select_Handler(file_reference_list:Array):void {
this.Debug("Select Handler: Received the files selected from the dialog. Processing the file list...");
var num_files_queued:Number = 0;
// Determine how many queue slots are remaining (check the unlimited (0) settings, successful uploads and queued uploads)
var queue_slots_remaining:Number = 0;
if (this.fileUploadLimit == 0) {
queue_slots_remaining = this.fileQueueLimit == 0 ? file_reference_list.length : (this.fileQueueLimit - this.queued_uploads); // If unlimited queue make the allowed size match however many files were selected.
} else {
var remaining_uploads:Number = this.fileUploadLimit - this.successful_uploads - this.queued_uploads;
if (remaining_uploads < 0) remaining_uploads = 0;
if (this.fileQueueLimit == 0 || this.fileQueueLimit >= remaining_uploads) {
queue_slots_remaining = remaining_uploads;
} else if (this.fileQueueLimit < remaining_uploads) {
queue_slots_remaining = this.fileQueueLimit;
}
}
// Check if the number of files selected is greater than the number allowed to queue up.
if (queue_slots_remaining < file_reference_list.length) {
this.Debug("Event: fileQueueError : Selected Files (" + file_reference_list.length + ") exceeds remaining Queue size (" + queue_slots_remaining + ").");
ExternalCall.FileQueueError(this.fileQueueError_Callback, this.ERROR_CODE_QUEUE_LIMIT_EXCEEDED, null, queue_slots_remaining.toString());
} else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -