一、简介和示例
SWFUpload is a small JavaScript/Flash library to get the best of both worlds. It features the great upload capabilities of Flash and the accessibility and ease of HTML/CSS。
官方站点:http://www.swfupload.org/
简单来说,swfupload这个上传库是可以显示上传进度以及上传速度等上传信息。一般实现这种上传体验有2种方式,一种是异步上传,在服务器端边接收数据边往session写入接收的字节数和进度数据,然后客户端轮询这个记录在session的进度数据并回显到页面。第二种方式就是采用flash来上传,也就是swfupload所采用的方式,在发送过程中将发送的相关状态数据回传到js的函数中处理。
下面是一个单个 文件上传 的使用示例,简单的创建一个SWFUpload对象,并传入相关的事件处理和参数就可以了:
01
|
var
swfu;
|
02
|
window.onload =
function
() {
|
03
|
swfu =
new
SWFUpload({
|
04
|
// Backend settings
|
05
|
upload_url:
"/upload"
,
|
06
|
file_post_name:
"image"
,
|
07
|
// Flash file settings
|
08
|
file_size_limit :
"10 MB"
,
|
09
|
file_types :
"*.*"
,
// or you could use something like: "*.doc;*.wpd;*.pdf",
|
10
|
file_types_description :
"All Files"
,
|
11
|
file_upload_limit :
"0"
,
|
12
|
file_queue_limit :
"5"
,
|
13
|
// Event handler settings
|
14
|
swfupload_loaded_handler : swfUploadLoaded,
|
15
|
|
16
|
file_dialog_start_handler: fileDialogStart,
|
17
|
file_queued_handler : fileQueued,
|
18
|
file_queue_error_handler : fileQueueError,
|
19
|
file_dialog_complete_handler : fileDialogComplete,
|
20
|
|
21
|
//upload_start_handler : uploadStart, // I could do some client/JavaScript validation here, but I don't need to.
|
22
|
upload_progress_handler : uploadProgress,
|
23
|
upload_error_handler : uploadError,
|
24
|
upload_success_handler : uploadSuccess,
|
25
|
upload_complete_handler : uploadComplete,
|
26
|
// Button Settings
|
27
|
button_image_url :
"/static/images/XPButtonUploadText_61x22.png"
,
|
28
|
button_placeholder_id :
"spanButtonPlaceholder"
,
//flash元素要替代的html元素
|
29
|
button_width: 61,
|
30
|
button_height: 22,
|
31
|
|
32
|
// Flash Settings
|
33
|
flash_url :
"/static/swf/swfupload.swf"
,
|
34
|
custom_settings : {
|
35
|
progress_target :
"fsUploadProgress"
,
|
36
|
upload_successful :
false
|
37
|
},
|
38
|
}
|
二、参数说明
原理是很明显易懂的,关键是flash和javascript的通讯部分,在 文件上传 的各个状态都会有javascript和flash函数的相互回调。目前主要研究了上传单个文件的上传逻辑,swfupload支持多个 文件上传 的,不过核心的逻辑应该是没有太多的变化。swfupload用一个队列来管理多个 文件上传 的,因为在传入的参数中会有一些队列和 文件上传 数量相关的参数。
在其核心的JavaScript文件swfupload.js定义的状态码以及从flash传递到js的文件对象:
01
|
//文件对象
|
02
|
file = {
|
03
|
"id"
:SWFUpload_0_0,
|
04
|
"index"
:0,
|
05
|
"filestatus"
:-1,
|
06
|
"name"
:vim-cheat-sheet-diagram.png,
|
07
|
"size"
:317949,
|
08
|
"type"
:
""
,
|
09
|
"creationdate"
:Fri Jan 16 1970 00:08:13 GMT+0800 (CST),
|
10
|
"modficationdate"
:Fri Jan 16 1970 00:08:13 GMT+0800 (CST),
|
11
|
"post"
: {}
|
12
|
}
|
13
|
|
14
|
//文件队列错误码
|
15
|
SWFUpload.QUEUE_ERROR = {
|
16
|
QUEUE_LIMIT_EXCEEDED : -100,
|
17
|
FILE_EXCEEDS_SIZE_LIMIT : -110,
|
18
|
ZERO_BYTE_FILE : -120,
|
19
|
INVALID_FILETYPE : -130
|
20
|
};
|
21
|
|
22
|
//上传错误码
|
23
|
SWFUpload.UPLOAD_ERROR = {
|
24
|
HTTP_ERROR : -200,
|
25
|
MISSING_UPLOAD_URL : -210,
|
26
|
IO_ERROR : -220,
|
27
|
SECURITY_ERROR : -230,
|
28
|
UPLOAD_LIMIT_EXCEEDED : -240,
|
29
|
UPLOAD_FAILED : -250,
|
30
|
SPECIFIED_FILE_ID_NOT_FOUND : -260,
|
31
|
FILE_VALIDATION_FAILED : -270,
|
32
|
FILE_CANCELLED : -280,
|
33
|
UPLOAD_STOPPED : -290
|
34
|
};
|
35
|
|
36
|
//文件状态
|
37
|
SWFUpload.FILE_STATUS = {
|
38
|
QUEUED : -1,
|
39
|
IN_PROGRESS : -2,
|
40
|
ERROR : -3,
|
41
|
COMPLETE : -4,
|
42
|
CANCELLED : -5
|
43
|
};
|
44
|
|
45
|
//按钮的动作
|
46
|
SWFUpload.BUTTON_ACTION = {
|
47
|
SELECT_FILE : -100,
|
48
|
SELECT_FILES : -110,
|
49
|
START_UPLOAD : -120
|
50
|
};
|
1. 事件处理函数
事件函数 | 触发时间 | 参数 |
swfupload_loaded_handler | 在flash初始化完成之后 | 没有参数 |
file_dialog_start_handler | 当用户点击上传按钮,在打开文件浏览窗口之前 | 没有参数 |
file_queued_handler | 用户成功地选择了文件,在file_dialog_complete_handler事件之前触发。如果选择了多个文件,则触发多次 | file文件对象 |
file_queue_error_handler | 文件上传 数量、类型、大小不符合时 | file文件对象、错误码、从flash中返回的错误信息 |
file_dialog_complete_handler | 在用户成功了选择了文件后,在所有file_queued_handler之后触发 | 选择文件的数量、加入了文件队列的文件数量、在当前文件队列总共的文件数量 |
upload_start_handler | 用户点击了提交按钮,开始把 文件上传 到服务器 | file文件对象 |
upload_progress_handler | 刚打开与服务器的连接与 文件上传 过程中 | file文件对象、已经上传的字节数、总共要上传的字节数 |
upload_error_handler | 上传失败时 | file文件对象、错误码、从flash中返回的错误信息 |
upload_success_handler | 文件上传 成功或者等待服务器数据返回超时 | file文件对象、服务器返回的数据、服务器是否有返回数据 |
upload_complete_handler | 上传完成时,在upload_success_handler之后触发 | file文件对象 |
debug_handler | 调用SWFUpload对象的debug()函数时 | swfupload对象和其初始化的参数 |
2. 其他重要参数
参数名 | 意义 | 说明 |
upload_url | 要上传到的服务器地址 | |
file_post_name | 上传到服务器中文件内容对应的key | |
flash_url | flash元素的url | |
custom_settings | 自定义的参数,可以在事件处理函数中获取得到 | dict类型 |
button_placeholder_id | flash的上传按钮显示在html的位置,此名称的元素会被替换成object元素 | span即可 |
三、上传逻辑
下面是用graphviz画出来的流程图,图比较大,不过看得舒服:)
1. 如上面的示例代码所示,在javascript代码中首先要创建一个SWFUpload的javascript对象,这个对象创建的初始化逻辑如下(箭头表示逻辑和流程的走向):
2. 当javascript将object元素添加到html页面的元素中时,即初始化flash中的元素:
3.用户点击上传的按钮,准备选择文件时,这个已经绑定了按钮的点击事件,而这个按钮不是input而是一个flash的元素:
4.用户选择完文件后:
5. 用户点击提交按钮,文件开始上传到服务器:
6.
文件上传
过程中的一些事件处理逻辑: