一、 簡單說明
Ajax+Flash多文件上傳是一個開源的上傳組件,名稱是FancyUpload,其官方網(wǎng)址是:http://digitarald.de/project/fancyupload/。這個組件僅僅是客戶端的應(yīng)用組件,即與任何服務(wù)器端的技術(shù)沒有關(guān)系,服務(wù)器端可以采用任何后臺技術(shù)(如JSP、Servlet、ASP等)。應(yīng)用該組件提供給我們的最大的好處有如下幾點(個人認(rèn)為,呵呵):
n 可以同時選擇多個文件進(jìn)行上傳;
n 以隊列的形式排列要上傳的文件和其相關(guān)信息(如名稱、大小等)(美觀^_^);
n 可以設(shè)置要上傳的文件個數(shù)、文件類型和文件大小(實用^_^);
n 有上傳進(jìn)度顯示(感覺這個非常直觀,很方便實用);
n 上傳的過程中可以隨時取消要上傳的文件;
n 平臺獨立性,由于使用flash和成熟的AJAX框架(mootools)可以避免對特定瀏覽器和服務(wù)器依賴!
n 使用簡單,文件體積小!(這個才是最實在的,呵呵)
n 表單無須設(shè)置enctype="multipart/form-data"了(這個有點意思吧)
二、 應(yīng)用部署
文件夾fancyupload中的文件就是該組件所需要到的所有文件了,包括四個JS、二個圖片、一個swf文件,另外還包含一個簡單的測試html頁面,其文件結(jié)構(gòu)如下:

將整個文件夾copy到你的web應(yīng)用目錄即可,使用的時候其步驟和代碼如下:
Ø 引入JS文件
在頁面上依次引入mootools-release-1.11.js、Swiff.Base.js、Swiff.Uploader.js、FancyUpload.js這四個JS,具體目錄請依據(jù)自己的情況進(jìn)行設(shè)置!
Ø 在頁面上設(shè)置CSS樣式(主要是文件列表和上傳進(jìn)度的樣式)
在head之間嵌入mytest.html中的css代碼!
Ø 在onload方法中調(diào)用如下代碼:
var upload = new FancyUpload(
$(“fileId”),
{
swf: 'Swiff.Uploader.swf'
}
);
我們只要這一行代碼就可以工作了,不過我們可以通過像設(shè)置swf一樣來設(shè)置多個參數(shù)來控制我們的上傳,比如是否使用隊列,控制文件大小等。相關(guān)的參數(shù)意義如下:
fileId 就是我們頁面上文件域的ID,即type為file的input元素的ID;
{} 這樣包起來的參數(shù)就是我們的可選參數(shù)了,可參考FancyUpload.js中的說明。
Ø 在頁面上設(shè)置類似mytest.html中的body區(qū)域的代碼即可!
來看一個文件上傳的實際效果,如下圖:

三、 FancyUpload的參數(shù)說明
u url
文件上傳的地址,如果不指定,那么將會自動取文件域所在的表單的action值來進(jìn)行上傳。如果表單的action也沒有指定值,那么將嘗試獲取路徑欄中的地址來進(jìn)行文件上傳。一般而言我們都需要指定該參數(shù)和文件域所在的表單的action兩者之一!
u swf
就是組件中的flash文件了,主要是用來選擇文件和過濾等,基本上可以不用設(shè)置。
u multiple
是否允許選擇多個文件,默認(rèn)是true。這個多選是指在打開的文件對話框中按住ctr鍵進(jìn)行多文件的選中。
u queued
是否允許隊列上傳,默認(rèn)是true。
u types
指定上傳文件的類型,采用的格式是 {提示信息:文件類型},如只允許媒體文件上傳的例子:{“媒體文件(*.rm,*.avi)” : “*.rm; *.avi”}
u limitSize
指定限制的文件大小,單位是字節(jié)!默認(rèn)是不限制,超過此值的文件將不被選中,注意即使選擇后系統(tǒng)也沒有提示,但是隊列中也是沒有該文件的!可以通過修改文件FancyUpload.js,在其128行的if語句中加上一個alert提示即可!
u limitFiles
限制的文件個數(shù),默認(rèn)是不限制!
u createReplacement
一個自定義函數(shù)(參數(shù)為文件域?qū)ο螅脕硖鎿Q文件域,默認(rèn)是被替換成為一個按鈕!具體的代碼可以參考FancyUpload.js中的第101到111行的代碼。默認(rèn)我已經(jīng)將其按鈕的值改成了中文的“瀏覽文件”。
u instantStart
表示選擇文件后是否立即開始上傳,默認(rèn)是false!也建議不要設(shè)置為true,上傳的操作我們可以交給該文件域所在表單的提交按鈕,這也是自動綁定的,無須我們做任何操作。
u allowDuplicates
是否允許隊列中選擇重復(fù)的文件,默認(rèn)是false!注釋中是true,而代碼中是false,所以以代碼中的為準(zhǔn)。
u container
flash文件的容器對象,默認(rèn)是document.body,可以不用修改!
u optionFxDuration
文件添加到隊列后,其高亮度到消失高亮度的時間,默認(rèn)是250ms!也就是漸逝的時間長度。
u queueList
來列表顯示文件隊列的容器對象或其ID。
u onComplete
單個文件上傳成功后調(diào)用的方法,非AJAX,無回調(diào)參數(shù)。每個文件上傳成功后都將調(diào)用該方法一次!
u onAllComplete
所有文件上傳成功后的調(diào)用方法!
四、 表單文件域和參數(shù)同時上傳實戰(zhàn)
在你自己試過這個上傳組件后,是不是感覺非常好用的,但同時你也或許發(fā)現(xiàn)了一個問題,那就是表單中的參數(shù)怎么進(jìn)行上傳的問題。因為該組件是采用FLASH+AJAX進(jìn)行上傳的,即頁面是不刷新的,而且上傳的過程中僅僅是上傳了你選擇的文件,而所有的表單非文件域參數(shù)則被忽略了。那我們?nèi)绾蝸磉M(jìn)行文件和參數(shù)的同步上傳呢,這里有幾個問題要注意的就是:
1) 由于該組件是綁定了表單的submit方法,所以不能夠直接在js中使用$(‘表單ID’).submit()這樣的方式來進(jìn)行表單上傳,否則參數(shù)是傳上去了而文件則沒有;
2) 如果沒有做設(shè)置那么只要選擇了文件而且觸發(fā)了表單的submit事件,那么該組件就會開始上傳文件,即使我們加了onsubmit方法中的return false也無效;
3) 在第二條的基礎(chǔ)上我們?nèi)绾伪WC用戶既選擇了文件而且又輸入了表單的所有必填參數(shù)呢?
這些問題在經(jīng)過本人一天的實際摸索后,終于得到了解決,呵呵,現(xiàn)說明如下:
1) 首先是上傳前的參數(shù)檢查
這包括表單中的必填參數(shù)和文件的選擇與否的判斷。既然我們無法通過直接點擊submit按鈕進(jìn)行提交前檢查,那么我們就用一個普通的按鈕,設(shè)置一個onclick事件,通過這個事件來進(jìn)行參數(shù)的檢查。這個即可避免選擇了文件但又沒有輸入?yún)?shù)的誤提交,又檢查了整個數(shù)據(jù)的完整性,其代碼如下:
<input type=”button” value=”提交” onclikc=”checkSubmit()” />
在checkSubmit方法中我們可以通過調(diào)用對象FancyUpload的fileList屬性來判斷用戶是否選擇了文件,其代碼如下(假設(shè)你的FancyUpload對象的實例名稱是uploader):
if (uploader. fileList.length < 1) {
alert(‘請選擇要上傳的文件!’);
}
通過判斷這個屬性(類型為數(shù)組)的長度來查看用戶是否選擇了文件,具體的個數(shù)就需要用戶自己進(jìn)行判斷了,我這里是一個文件。
2) 表單提交
參數(shù)檢查完整后我們就可以開始上傳文件和表單參數(shù)了,這里我們的文件和表單參數(shù)是無法一起提交的,我們只能分先文件上傳,上傳成功后再提交我們的表單參數(shù)。
第一步是文件的上傳,之前也已經(jīng)提過了不能夠直接在JS中進(jìn)行表單的submit,否則就無法上傳文件了,這里我們采用一個迂回的辦法,在表單中隱藏一個提交按鈕,代碼如下:
<input type=”submit” id=”mysubmit” style=”display:none” />
然后我們再在checkSubmit函數(shù)的最后加上如下代碼:
……
$(“mysubmit”).submit();
……
這樣,我們通過一個隱藏提交按鈕來觸發(fā)表單的submit事件,這樣我們就可以順利的進(jìn)行文件上傳了。
第二步,在文件上傳成功后,我們再進(jìn)行參數(shù)的提交,文件上傳成功的觸發(fā)函數(shù)我們在FancyUpload對象的onComplete上進(jìn)行定義,不過對于多文件上傳的就要定義在onAllComplete上了,我建議全部定義在onAllComplete上,如下:
onAllComplete:function() {
$(“你的表單的Id”).submit();
}
在這里我們就可以直接調(diào)用表單的submit來提交參數(shù)了,當(dāng)然了你也可以采用AJAX提交,那就要看自己的需求了。
3) 上傳文件的路徑和表單參數(shù)的綁定
由于我們的文件上傳和表單參數(shù)上傳是分成兩個部分進(jìn)行上傳的,這就出現(xiàn)了如何將兩次上傳的參數(shù)進(jìn)行綁定的問題。而且查看官方上的評論,作者也沒有給出解決方法,而且該組件只能檢測錯誤時的狀態(tài)碼(00 < status < 300),對于上傳成功是無法獲取任何返回信息的。目前我的解決方法就是:
1. 文件上傳成功后將路徑信息存儲以原始文件名為key存儲在session中;
2. 參數(shù)進(jìn)行上傳時根據(jù)原始文件的名稱去從session中獲取上傳的路徑信息
通過這二步基本上就可以綁定兩次上傳的參數(shù)了!如果有更好的方法大家也可以一起探討。
所以通過以上三個步驟后我們就可以實現(xiàn)文件的無刷新上傳和進(jìn)度顯示了!^_^另外這個分步進(jìn)行上傳是相對表單參數(shù)比較多的情況,如果參數(shù)比較少的話可以直接將參數(shù)附加在URL地址后面進(jìn)行也是可以的,這就要靠個人的發(fā)揮了。