一、簡介和示例

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。

官方站點(diǎn):http://www.swfupload.org/

簡單來說,swfupload這個(gè)上傳庫是可以顯示上傳進(jìn)度以及上傳速度等上傳信息。一般實(shí)現(xiàn)這種上傳體驗(yàn)有2種方式,一種是異步上傳,在服務(wù)器端 邊接收數(shù)據(jù)邊往session寫入接收的字節(jié)數(shù)和進(jìn)度數(shù)據(jù),然后客戶端輪詢這個(gè)記錄在session的進(jìn)度數(shù)據(jù)并回顯到頁面。第二種方式就是采用 flash來上傳,也就是swfupload所采用的方式,在發(fā)送過程中將發(fā)送的相關(guān)狀態(tài)數(shù)據(jù)回傳到j(luò)s的函數(shù)中處理。

下面是一個(gè)單個(gè)文件上傳的使用示例,簡單的創(chuàng)建一個(gè)SWFUpload對象,并傳入相關(guān)的事件處理和參數(shù)就可以了:

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}

二、參數(shù)說明

原理是很明顯易懂的,關(guān)鍵是flash和javascript的通訊部分,在文件上傳的各個(gè)狀態(tài)都會有javascript和flash函數(shù)的相互 回調(diào)。目前主要研究了上傳單個(gè)文件的上傳邏輯,swfupload支持多個(gè)文件上傳的,不過核心的邏輯應(yīng)該是沒有太多的變化。swfupload用一個(gè)隊(duì) 列來管理多個(gè)文件上傳的,因?yàn)樵趥魅氲膮?shù)中會有一些隊(duì)列和文件上傳數(shù)量相關(guān)的參數(shù)。

在其核心的JavaScript文件swfupload.js定義的狀態(tài)碼以及從flash傳遞到j(luò)s的文件對象:

01//文件對象
02file = {
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//文件隊(duì)列錯(cuò)誤碼
15SWFUpload.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//上傳錯(cuò)誤碼
23SWFUpload.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//文件狀態(tài)
37SWFUpload.FILE_STATUS = {
38    QUEUED       : -1,
39    IN_PROGRESS  : -2,
40    ERROR        : -3,
41    COMPLETE     : -4,
42    CANCELLED    : -5
43};
44 
45//按鈕的動作
46SWFUpload.BUTTON_ACTION = {
47    SELECT_FILE  : -100,
48    SELECT_FILES : -110,
49    START_UPLOAD : -120
50};

1. 事件處理函數(shù)

事件函數(shù)觸發(fā)時(shí)間參數(shù)
swfupload_loaded_handler在flash初始化完成之后沒有參數(shù)
file_dialog_start_handler當(dāng)用戶點(diǎn)擊上傳按鈕,在打開文件瀏覽窗口之前沒有參數(shù)
file_queued_handler用戶成功地選擇了文件,在file_dialog_complete_handler事件之前觸發(fā)。如果選擇了多個(gè)文件,則觸發(fā)多次file文件對象
file_queue_error_handler文件上傳數(shù)量、類型、大小不符合時(shí)file文件對象、錯(cuò)誤碼、從flash中返回的錯(cuò)誤信息
file_dialog_complete_handler在用戶成功了選擇了文件后,在所有file_queued_handler之后觸發(fā)選擇文件的數(shù)量、加入了文件隊(duì)列的文件數(shù)量、在當(dāng)前文件隊(duì)列總共的文件數(shù)量
upload_start_handler用戶點(diǎn)擊了提交按鈕,開始把文件上傳到服務(wù)器file文件對象
upload_progress_handler剛打開與服務(wù)器的連接與文件上傳過程中file文件對象、已經(jīng)上傳的字節(jié)數(shù)、總共要上傳的字節(jié)數(shù)
upload_error_handler上傳失敗時(shí)file文件對象、錯(cuò)誤碼、從flash中返回的錯(cuò)誤信息
upload_success_handler文件上傳成功或者等待服務(wù)器數(shù)據(jù)返回超時(shí)file文件對象、服務(wù)器返回的數(shù)據(jù)、服務(wù)器是否有返回?cái)?shù)據(jù)
upload_complete_handler上傳完成時(shí),在upload_success_handler之后觸發(fā)file文件對象
debug_handler調(diào)用SWFUpload對象的debug()函數(shù)時(shí)swfupload對象和其初始化的參數(shù)

2. 其他重要參數(shù)

參數(shù)名意義說明
upload_url要上傳到的服務(wù)器地址
file_post_name上傳到服務(wù)器中文件內(nèi)容對應(yīng)的key
flash_urlflash元素的url
custom_settings自定義的參數(shù),可以在事件處理函數(shù)中獲取得到dict類型
button_placeholder_idflash的上傳按鈕顯示在html的位置,此名稱的元素會被替換成object元素span即可

三、上傳邏輯

下面是用graphviz畫出來的流程圖,圖比較大,不過看得舒服:)
1. 如上面的示例代碼所示,在javascript代碼中首先要?jiǎng)?chuàng)建一個(gè)SWFUpload的javascript對象,這個(gè)對象創(chuàng)建的初始化邏輯如下(箭頭表示邏輯和流程的走向):
js_swfupload
2. 當(dāng)javascript將object元素添加到html頁面的元素中時(shí),即初始化flash中的元素:
flash_swfupload
3.用戶點(diǎn)擊上傳的按鈕,準(zhǔn)備選擇文件時(shí),這個(gè)已經(jīng)綁定了按鈕的點(diǎn)擊事件,而這個(gè)按鈕不是input而是一個(gè)flash的元素:
open_filebrowser
4.用戶選擇完文件后:
select_file
5. 用戶點(diǎn)擊提交按鈕,文件開始上傳到服務(wù)器:
submit_upload
6. 文件上傳過程中的一些事件處理邏輯:
upload_events