SWFUpload
SWFUpload最初是由Vinterwebb.se开发的一个客户端的上传工具. 它结合了FLASH和JavaScript的功能,以提供一种超越了传统的浏览器中<input type="file" />标签提供的文件上传功能。
SWFUpload提供的主要功能:
- 在文件选择对话框中能够进行文件多选
- 页面无刷新的上传
- 提供上传进度的事件回调,实时显示上传进度
- 良好的浏览器兼容性
- 采用了命名空间以兼容其它JS的库 (例如 jQuery, Prototype, 等等)
对FLASH 8和FLASH 9播放器的支持- 对FLASH 9和FLASH 10播放器的支持(V2.2.0版本放弃了对Flash 8的支持)
SWFUpload背后的设计思想和其它基于Flash的上传工具是不同的。它将浏览器的中UI交给开发人员来控制。开发人员能够利用 XHTML,CSS,Javascript来定制符合他们网站风格的UI上传元素。然后使用它提供的一组简单的JS事件来更新上传状态,开发人员能够利用 这些事件来及时更新页面中的上传进度UI。
不幸的是Flash Player 10 更严格的安全机制迫使我们不得不将一个Flash Button放入Flash影片中。SWFUpload提供API供开发者通过图片、文字、CSS的方式来自定制更灵活的UI显示。
SWFUpload v2
SWFUpload v2包含了新的高级功能,改善了稳定性,解决了FlashPlayer中的一些bug,并且提供一套有用的插件。新的功能包括:
- 兼容了Flash Player 10的安全限制问题
- 在文件上传的同时能够发送额外的POST数据
- 针对每一个文件上传发送POST/GET数据
- 更直观的事件回调
- 动态修改实例设置
- 接收服务端返回的数据
- 非取消形式的停止文件上传
- 自定义上传的顺序
- 支持单文件、多文件的文件的选择
- 文件入队数量,文件上传数量和文件大小的限制
- 更合理地处理0字节的文件
- 针对每个文件在上传前都提供一个最后确认的时间回调
- 解决了v1.0.2版本中未描述到的关于Flash的bug
- 解决的v1.0.2中的bug:
- 在IE中,刷新的时候FLASH无法加载(详细可见我之前的debug过程)
- 在FireFox中,如果窗口的滚动条没有回滚到顶部,那么Flash无法加载
- Race-conditions when files are cached
- 兼容ASP.Net Forms
SWFUpload v2 延续了SWFUpload的设计目标,将UI分离以交给开发人员控制和后续扩展
概述
传统的HTML上传
标准的HTML上传表单为用户提供一个文本框和按钮来选择文件,选中的文件是随着form表单提交的。整个文件上传完成之后,下一个页面才会显示,并且不能对选择的文件做预设的文件检验,例如文件大小限制,文件类型限制。当文件上传时,用户获得的可用的反馈信息很少。
传统的HTML上传模式十分简单,线性的,几乎所有浏览器都支持它。
SWFUpload
SWFUpload使用一个隐藏的Flash影片来控制文件的选择和上传。JavaScript用来激活文件选择对话框。 此文件选择对话框是可以设置允许用户选择一个单独的文件或者是多个文件。
SWFUpload 使用一个Flash影片来控制文件的选择和上传。此FLASH中包含一个用户自定制UI的按钮,点击该按钮能够激活Flash本身的高级文件上传对话框, 它能够根据用户的设置来进行单文件或者是多文件的上传。 选择的的文件类型也是可以被限制的,因此用户只能选择指定的适当的文件,例如*.jgp;*.gif。
提醒:Flash Player 10的安全机制更严格,类似打开文件上传的对话框的操作,一定需要用户交互才触发,如果用脚本触发,会报#2176的运行时错误。因此V2.2.0版本在SWF中添加了一个可定制的Button让用户交互来打开文件对话框。
当选定文件以后,每个文件都会被验证和处理。当Flash上传文件的时候,由开发人员预定义的Javascript事件会被定时触发以便来更新页面中的UI,同时还提供上传状态和错误信息。
选定的文件的上传和它所在页面、表单是独立的。每个文件都是单独上传的,这就保证了服务端脚本能够在一个时间点更容易地处理单个文件。虽然 Flash提供了上传服务,但是页面并不会提交或者重新载入。相比于标准的HTML Form,SWFUpload的使用方式更像是AJAX程序,页面中的Form会和FLASH控制的文件上传单独处理。
入门
SWFUpload并不是拖放式的上传控件,它需要JavaScript和DOM的知识。一些可用的演示展示了它能够完成什么事情以及它是如何完成这些常见的任务。
SWFUpload由4部分组成:
- 初始化和设置(Javascript)
- JavaScript 库: SWFUpload.js
Flash控制元素: SWFUpload_f8.swf 或者 SWFupload_f9.swfSWFUpload.swf(V2.2.0版本放弃了对flash 8的支持)- 事件处理(Javascript)
使用SWFUpload遇到的多数问题是由不正确地设置或者定义了糟糕的处理事件引起的。
初始化和设置
SWFpload必须在页面中初始化,一般可以在window.onload事件中完成此操作。它的构造函数需要一个Object类型的设置对象。 这个设置对象一般是一个直接定义的Object类型变量,直接传递给SWFUpload的构造函数。
初始化的SWFUpload对象的引用需要保留下来,因为当显示文件选择对话框和启动文件上传的时候需要这个实例的引用。
例如:用直接定义的Object类型变量设置初始化SWFUpload对象
var swfu; window.onload = function () {
swfu = new SWFUpload({
upload_url : "http://www.swfupload.org/upload.php",
flash_url : "http://www.swfupload.org/swfupload.swf",
button_placeholder_id : "spanSWFUploadButton",
file_size_limit : "20480"
});
};
例如:用存储在变量中的设置对象初始化SWFUpload对象
var swfu;
window.onload = function () {
var settings_object = {
upload_url : "http://www.swfupload.org/upload.php",
flash_url : "http://www.swfupload.org/swfupload.swf",
button_placeholder_id : "spanSWFUploadButton", file_size_limit : "20480"
};
swfu = new SWFUpload(settings_object);
};
JavaScript 库
该JavaScript库文件(swfupload.js)应该包含在需要上传功能的页面中。
当SWFUpload创建完成并能访问它的一系列功能时,开发人员可以来控制此实例。
例如: 添加SWFUpload.js到页面中
<script type="text/javascript" src="http://www.swfupload.org/swfupload.js"></script>
例如: 根据需要的设置来初始化SWFUpload,同时把它的seleteFiles方法绑定到一个按钮的Click事件上。
var swfu = new SWFUpload({ upload_url : "http://www.swfupload.org/upload.php", flash_url : "http://www.swfupload.org/swfupload.swf", button_placeholder_id : "spanSWFUploadButton" });
document.getElementById("BrowseButton").onclick = function () { swfu.selectFiles(); };
Flash 控制元素
SWFUpload JavaScript库动态加载Flash控制元素(swfupload.swf)。该Flash控制元素有两个版 本。swfupload_f8.swf支持Flash Player8以及更高版本。它在提供了更好的兼容性同时牺牲了一些功能。swfupload_f9.swf支持Flash Player9.0.28以及更高版本。它在提供了额外的功能同时牺牲了使用Flash Player8的用户。
Flash控制元素的文件地址在初始化的时候就应该在SWFUpload设置对象中定义。
Flash控制元素是一个很小的的Flash影片,它提供了文件浏览、检验和上传功能。它在页面中展现给用户的是一个UI可自定制的按钮,但该Flash会在需要时候通过与Javascript通信来通知浏览器处理更新。
事件处理
开发人员必须定义一系列JavaScript函数来处理SWFUpload事件回调,当一些不同的重要事件发生的时候,这些函数会被触发。
通过处理SWFUpload的事件,开发人员能够提供关于上传进度、出错信息以及上传完成等的信息反馈。
例如: swfupload的处理事件和初始化
// uploadStart处理事件。
该函数变量在设置对象中指定给了upload_start_handler属性。
var uploadStartEventHandler = function (file) {
var continue_with_upload;
if (file.name === "the sky is blue") {
continue_with_upload = true;
} else {
continue_with_upload = false;
}
return continue_with_upload;
};
//uploadSuccess处理事件。
该函数变量在设置对象中指定给了upload_success_handler属性。
var uploadSuccessEventHandler = function (file, server_data) {
alert("The file " + file.name + " has been delivered to the server.");
alert("The server responded with " + server_data);
};
//创建SWFUpload实例,设置事件回调函数
var swfu = new SWFUpload({
upload_url : "http://www.swfupload.org/upload.php",
flash_url : "http://www.swfupload.org/swfupload.swf",
file_size_limit : "20480",
upload_start_handler : uploadStartEventHandler,
upload_success_handler : uploadSuccessEventHandler
});
SWFUpload JavaScript 对象
构造函数
SWFUpload(settings object)
返回:一个SWFUpload 实例
var swfupload_instance = new SWFUpload(settings_object);
全局变量和常量
SWFUpload定义了一些全局变量和常量,这对SWFUpload的高级应用程序和处理错误都是很有用的,它们都是只读的。
SWFUpload.instances
SWFUpload.instances是一个存储了页面中所有SWFUpload实例引用的数组。Flash播放器依靠这个数组来调用正确的处理 事件。该数组是由movieName属性来索引的关联数组。例如:SWFUpload.instances.SWFUpload_0访问的是第一个实例引 用。
注意: SWFUpload.instances不是一个真正的JavaScript数组,实际上它是一个对象(关联数组)。
SWFUpload.movieCount
SWFUpoad.movieCount是一个全局变量,用于记录页面中的SWFUpload实例个数,同时确保给每一个Flash影片分配一个惟一的movieName。
SWFUpload.QUEUE_ERROR
SWFUpload.QUEUE_ERROR是一个包含了Queue Error错误码的JS对象,一般用它来查看fileQueueError事件的中发送的错误码,以确定fileQueueError的具体类型。
SWFUpload.QUEUE_ERROR = { QUEUE_LIMIT_EXCEEDED : -100, FILE_EXCEEDS_SIZE_LIMIT : -110, ZERO_BYTE_FILE : -120, INVALID_FILETYPE : -130 };
SWFUpload.UPLOAD_ERROR
SWFUpload.UPLOAD_ERROR是一个包含了Upload Error错误码的JS对象,一般用它来查看uploadError事件的中发送的错误码,以确定uploadError的具体类型。
SWFUpload.UPLOAD_ERROR = { HTTP_ERROR : -200, MISSING_UPLOAD_URL : -210, IO_ERROR : -220, SECURITY_ERROR : -230, UPLOAD_LIMIT_EXCEEDED : -240, UPLOAD_FAILED : -250, SPECIFIED_FILE_ID_NOT_FOUND : -260, FILE_VALIDATION_FAILED : -270, FILE_CANCELLED : -280, UPLOAD_STOPPED : -290 };
SWFUpload.FILE_STATUS
SWFUpload.FILE_STATUS是一个包含File Status状态码的JS对象。它可以用来检测File对象中的file status属性,以确定文件的状态。
SWFUpload.FILE_STATUS = { QUEUED : -1, IN_PROGRESS : -2, ERROR : -3, SUCCESS : -4, CANCELLED : -5 };
默认处理事件
SWFUpload库提供了一系列默认的处理事件。当开发人员没有自定义处理事件时,SWFUpload库将调用这些默认的处理事件。因此当自定义事件时,不要把这些默认的处理事件覆盖了。自定义事件是需要在settings对象中被单独定义的。
SWFUpload.BUTTON_ACTION
SWFUpload.BUTTON_ACTION是一个包含button的动作预设的JS对象。
SWFUpload.BUTTON_ACTION = { SELECT_FILE : -100, SELECT_FILES : -110, START_UPLOAD : -120 }
可以使用button_action属性来设置Flash本身的文件上传对话框的行为。默认为 SWFUpload.BUTTON_ACTION.SELECT_FILES,点击按钮将会打开多文件上传的对话框。如果设置为 SWFUpload.BUTTON_ACTION.SELECT_FILE,则为单文件上传。如果设置为 SWFUpload.BUTTON_ACTION.START_UPLOAD,则启动文件上传
SWFUpload.CURSOR
SWFUpload.CURSOR是一个包含button的光标状态码的JS对象。
SWFUpload.CURSOR = { ARROW : -1, HAND : -2 }
可以使用button_cursor属性来设置鼠标划过button时的光标状态。默认为SWFUpload.CURSOR.ARROW,如果设置为SWFUpload.CURSOR.HAND,则为手形
SWFUpload.WINDOW_MODE
SWFUpload.WINDOW_MODE是一个包含了该SWF插入到页面中的wmode属性的JS对象.可以通过设置button_window_mode属性来告诉浏览器具体以哪种模式显示此SWF。
SWFUpload.WINDOW_MODE = { WINDOW : "window", TRANSPARENT : "transparent", OPAQUE : "opaque" };
SWFUpload.WINDOW_MODE.WINDOW是默认的模式. 该SWF将位于页面元素的最高层级。
SWFUpload.WINDOW_MODE.OPAQUE 该SWF可以被页面类的其他元素通过层级的设置来覆盖它。
SWFUpload.WINDOW_MODE.TRANSPARENT 该SWF的背景是透明的,可以透过它看到背后的页面元素。
属性
下面这个列表是相关属性的具体描述。使用其它属性或者对只读属性进行了写的操作都会造成SWFUpload出现问题。
customSettings (可读/可写)
customSettings属性是一个空的JavaScript对象,它被用来存储跟SWFUpload实例相关联的数据。它的内容可以使用设置对象中的custom_settings属性来初始化。
注意:一些插件使用customSettings对象来实现它们的内部控制。当重写整个customSettings对象的时候需要务必小心。
例如:
// 初始化包含自定义设置的SWFUpload对象 var swfu = new SWFUpload({ custom_settings : { custom_setting_1 : "custom_setting_value_1", custom_setting_2 : "custom_setting_value_2", custom_setting_n : "custom_setting_value_n", } }); swfu.customSettings.custom_setting_1 = "custom_setting_value_1"; // 更改一个存在的自定义设置 swfu.customSettings.myNewCustomSetting = "new custom setting value"; // 添加一个新的自定义设置 //用一个全新的对象重写customSettings swfu.customSettings = { custom_setting_A : "custom_setting_value_A", custom_setting_B : "custom_setting_value_B" };
movieName(只读)
包含了该SWFUpload实例的惟一影片名字。该值被传递给Flash,用来完成Flash和JavaScript的通信。该值被用来索引实例在SWFUpload.instances数组中的位置,你无法更改此值。
方法
下面的方法用来操作SWFUpload。其中有些方法可以跟元素(例如,按钮)的点击事件绑定,其它的方法供SWFUpload内部处理事件中调用。
object addSetting(setting_name, value, default_value)
不赞成使用 V2.1.0源码中注释:addSetting和getSetting已经不再被使用了,只是考虑到兼容V2版本,才继续保留在库中。
object getSetting(setting_name)
不赞成使用 V2.1.0源码中注释:addSetting和getSetting已经不再被使用了,只是考虑到兼容V2版本,才继续保留在库中。
object retrieveSetting(setting_value, default_value)
v2.1.0中已被删除
bool destroy()
v2.1.0中新增
用于将一个SWFUpload实例从页面中销毁。不但删除DOM中的Flash元素,同时还删除SWFUpload实例的相关引用。成功返回true,失败返回false。
这个方法还没有针对插件做兼容测试,可能会有不兼容问题。(尤其是SWFObject插件)
提醒:SWFUpload在v2.1.0中改写了Flash插入的代码,V2版中使用SWFObject插入Flash会造成IE的一个刷新BUG。
void displayDebugInfo()
调用debug方法,在Debug输出框中显示SWFUpload实例的设置信息,如果设置中的debug属性是true,那么默认是在实例化完成以后自动调用此方法。
void selectFile()
不赞成使用,不兼容Flash Player 10
弹出flash的文件选择对话框,只能选择单个文件。
提醒:Flash Player 10的安全机制更严格,类似打开文件上传的对话框的操作,一定需要用户交互才触发,如果用脚本触发,会报#2176的运行时错误。因此V2.2.0版本在SWF中添加了一个可定制的Button让用户交互来打开文件对话框。
void selectFiles()
不赞成使用,不兼容Flash Player 10
弹出flash的文件选择对话框,可一次性选择多个文件。
提醒:Flash Player 10的安全机制更严格,类似打开文件上传的对话框的操作,一定需要用户交互才触发,如果用脚本触发,会报#2176的运行时错误。因此V2.2.0版本在SWF中添加了一个可定制的Button让用户交互来打开文件对话框。
void startUpload(file_id)
指定file_id来启动该文件的上传,如果file_id被忽略了,那么默认开始上传第一个文件。
void cancelUpload(file_id, trigger_error_event)
指定file_id来退出文件的上传,从上传队列中删除该文件。
如果忽略file_id,那么默认文件上传队列中的第一个文件将被退出上传。
如果取消的文件是正在上传,那么会触发uploadError事件。
如果将可选参数trigger_error_event设置为false,那么uploadError事件不会触发。
void stopUpload()
如果当前有文件上传,那么停止上传,并且将文件还原到上传队列中。
停止了正在上传的文件,uploadError事件会被触发。如果此时没有正在上传文件,那么不会发生任何操作,不会触发任何事件。
object getStats()
获取当前状态的统计对象,具体见Stats Object。
void setStats(stats_object)
Stats统计对象是可以被修改的。如果你希望在上传完毕之后修改上传成功或者上传失败的统计数目时,那么可以使用该方法。
提醒:可供修改的属性只有successful_uploads ,upload_errors,upload_cancelled,queue_errors,并且值必须是Number类型。
object getFile(file_id|index)
根据file_id或者index来获取文件队列中的文件对象。file_id是文件对象中的id属性,index是文件对象中的index属性。
传递Number类型的参数会被认定为index,那么返回的是文件队列(所有尝试入队文件,包括因没有通过文件大小、类型检测等而触发 fileQueueError,没有成功加入文件上传队列的文件对象)数组中下标为index的文件对象。如果index不在队列数组范围内,那么返回 null。
传递非Number类型的参数会被认定为file_id,那么返回的是文件上传队列(通过文件检测,准备好进行上传的文件)数组中id为 file_id的文件对象。如果参数为空,或者没有此id的文件对象,那么返回文件等待队列中的第一个文件对象,如果第一个文件对象为空,那么返回 null。
void addPostParam(name, value)
给设置中的post_params对象添加值对,当文件上传的时候,这个值对会一同在POST中发送。
如果设置的时候,post_params中以及存在该值,那么实际上会被覆盖。