天天看點

SWFUpload使用指南

内容簡介

​ 由于在最近的項目中需要完成多檔案的上傳功能需求,要求相容ie6及其以上版本,這裡使用SWFUpload插件,要注意此插件是基于flash的,本文主要介紹了SWFUpload的基本用法和注意事項還有工作中遇到的一些問題。

SWFUpload特點

  • 允許一次上傳多個檔案,但會有一個上傳隊列,隊列裡檔案的上傳是逐個進行的,伺服器端接收檔案時跟普通的表單上傳檔案是一樣的;
  • 類似AJAX的無重新整理上傳;
  • 可以顯示上傳進度;
  • 良好的浏覽器相容性;
  • 相容其他JavaScript庫 (例如:jQuery), Prototype等);
  • 可以在浏覽器端就對要上傳的檔案進行限制;
  • 提供了豐富的事件接口供開發者使用;

SWFUpload參數設定

這裡使用的是V2.2.0版本,首先在頁面引入相關js

<script src='/swfupload/swfupload.js'></script>
<script src='/swfupload/swfupload.queue.js'></script>
<script src='/swfupload/fileprogress.js'></script>
<script src='/swfupload/handlers.js'></script>
           

然後配置參數

<!-- Html Code-->
<div id="FileList"></div>
<div id="spanSWFUpload">
	<span id="spanSWFUploadButton"></span>
</div>
<button type="button" id="ubutton">上傳</button>
           
var swfu;
var settings_object = {
	upload_url: "ServerURL",//伺服器位址
	flash_url: "/swfupload/swfupload.swf",//swf檔案路徑
	button_placeholder_id: "spanSWFUploadButton",
	file_size_limit: "20MB", //設定檔案選擇對話框的檔案大小過濾,該屬性可接收一個帶機關的數值,可用的機關有B,KB,MB,GB。如果忽略了機關,那麼預設使用KB。特殊值0表示檔案大小無限制。
	file_upload_limit: 12, //設定SWFUpload執行個體允許上傳的最多檔案數量
	file_queue_limit: 12, //設定檔案上傳隊列中等待檔案的最大數量限制
	button_width: "60",
	button_height: "18",
	button_text: '<span class="theFont">添加檔案</span>',
	button_text_style: ".theFont { font-size: 12;}",
	button_text_left_padding: 5,// 設定Flash Button上文字距離左側的距離,可以使用負值。
	button_text_top_padding: 0,//設定Flash Button上文字距離頂部的距離,可以使用負值。
	//button_action: SWFUpload.BUTTON_ACTION.SELECT_FILE, //設定每次隻能選擇1個檔案
	post_params: {}, //選填,檔案上傳時附帶的參數,也可以在後續動态添加
	use_query_string: false,//設定post_params是否以GET方式發送。如果為false,那麼則以POST形式發送。
	requeue_on_error: false,//當檔案對象發生uploadError時,檔案的處理方式,如果為true,該檔案對象會被重新插入到檔案上傳隊列的前端,而不是被丢棄。
	file_types: "*.doc;*.docx;*.pdf;*.xls;*.xlsx",
	button_cursor: SWFUpload.CURSOR.HAND,//設定滑鼠劃過Flash Button時的光标狀态。
    //下面為一系列的回調函數,在文章的後續部分會一一介紹
	file_queued_handler: fileQueued,
	file_queue_error_handler: fileQueueError,
	upload_start_handler: uploadStart,
	upload_error_handler: uploadError,
	upload_success_handler: uploadSuccess,
	upload_complete_handler: uploadComplete
	};
	swfu = new SWFUpload(settings_object);//建立一個SWFUpload對象,并将配置的參數設定進去
	//綁定上傳按鈕,點選開始上傳
	document.getElementById("ubutton").onclick = function (ev) {
         swfu.startUpload();
    }
           

​ 寫到這裡,我們的上傳就已經可以使用了,但是沒有任何的提示,需要注意的是,預設情況下,你選擇了檔案并關閉了檔案選擇對話框檔案并不會自動開始上傳,你需要調用SWFUpload的startUpload()方法,該方法接收一個file_id作為參數,如果參數為空,則自動開始上傳檔案隊列中的第一個檔案。選擇完檔案後如果檔案會自動開始上傳,可以将 handles.js 中的 this.startUpload()注釋掉即可。Swfupload雖支援批量上傳,但本質仍是單個檔案依次上傳,也就是說,每次上傳檔案都是一次獨立的請求。

回調函數

  • **file_queued_handler:fileQueued(file object) ** 當檔案選擇對話框關閉消失時,如果選擇的檔案成功加入上傳隊列,那麼針對每個成功加入的檔案都會觸發一次該事件(N個檔案成功加入隊列,就觸發N次此事件,我們可以在這裡完成已選擇檔案清單的展示功能。
//File Object包含了一組可用的檔案屬性
	{
		id : string, // SWFUpload控制的檔案的id,通過指定該id可啟動此檔案的上傳、退出上傳等
		index : number, // 檔案在標明檔案隊列(包括出錯、退出、排隊的檔案)中的索引,getFile可使用此索引
		name : string, // 檔案名,不包括檔案的路徑。
		size : number, // 檔案位元組數
		type : string, // 用戶端作業系統設定的檔案類型
		creationdate : Date, // 檔案的建立時間
		modificationdate : Date,	// 檔案的最後修改時間
		filestatus : number // 檔案的目前狀态
	}
	
           
  • file_queue_error_handler:fileQueueError(file object, error code, message) 當選擇檔案入隊失敗時觸發,每個出錯的檔案都會觸發一次該事件,檔案添加隊列出錯的原因可能有:超過了上傳大小限制(-110),檔案為零位元組(-120),超過檔案隊列數量限制(-100),設定之外的無效檔案類型(-130)。
  • upload_start_handler:uploadStart(file object) ** 在檔案往服務端上傳之前觸發此事件,可以在這裡完成上傳前的最後驗證以及其他你需要的操作,例如添加、修改、删除post資料**等。在完成最後的操作以後,如果函數傳回false,那麼這個上傳不會被啟動,并且觸發uploadError事件,如果傳回true或者無傳回,那麼将正式啟動上傳。
  • **upload_error_handler:uploadError(file object, error code, message) **隻要上傳被終止或者沒有成功完成,那麼該事件都将被觸發。具體的錯誤代碼如下:
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
     };
           
  • upload_success_handler:uploadSuccess(file object, server data) 當檔案上傳的處理已經完成(這裡的完成隻是指向目标處理程式發送了Files資訊,隻管發,不管是否成功接收),并且服務端傳回了200的HTTP狀态時,觸發此事件。在window平台下,服務端的處理程式在處理完檔案存儲以後,必須傳回一個非空值,否則此事件不會被觸發
  • upload_complete_handler:uploadComplete(file object) 當上傳隊列中的一個檔案完成了一個上傳周期,無論是成功(uoloadSuccess觸發)還是失敗(uploadError觸發),此事件都會被觸發,這也标志着一個檔案的上傳完成,可以進行下一個檔案的上傳了。
  • upload_progress_handler:uploadProgress(file object, bytes complete, total bytes) 該事件由flash定時觸發,提供三個參數分别通路上傳檔案對象、已上傳的位元組數,總共的位元組數。是以可以在這個事件中來定時更新頁面中的UI元素,以達到及時顯示上傳進度的效果。注意:該事件在Linux版本的Flash Player中存在問題,目前還無法解決。

    這些回調函數可以幫助我們做很多事情,比如在檔案加入隊列之前做的一些校驗,比如我們可以在檔案fileQueued()方法中完成檔案入隊前的一些校驗,并通過cancelUpload(fileId)(會觸發uploadError事件)方法來将檔案移除隊列。

有關參數的傳遞

在SWFUpload的配置參數中的post_params參數是用來向背景傳遞參數的,如果無法傳遞,請嘗試将另一個配置參數use_query_string設定為true之後就可以傳遞參數了。該參數接收一個JS對象:

post_params: {  
    param1: 'Hello',  
    param2: '你好'  
} 
           

但是如果參數值中含有中文的話,那麼背景會報錯,也取不到值,可以這樣解決:

post_params: {  
    param1: encodeURI('你好',"utf-8")  
} 
           

然後在背景再decode回來,以Java為例:

其他問題

  • 檔案上傳完成後的頁面跳轉: 可以通過監聽uploadSuccess(file object, server data)方法,通過JS控制挑轉,該事件在每個檔案上傳成功均會觸發如果同時在上傳多個檔案,那麼第一個檔案上傳完成後頁面就直接跳轉了,後面的檔案将不會上傳,可以通過SWFUpload.getStats().files_queued是否為0來判斷是否還有未上傳的檔案。
  • 在非IE浏覽器中Session不同的問題: 這是由于Flash Player在非IE浏覽器下一個Bug引起的,導緻使用者登入的Session和檔案上傳産生的Session不同,也就是說檔案上傳另生成了一個新的Session。解決辦法是手動将SessionID傳到背景服務端,在上傳路徑URL裡加上jsessionid變量即可。

常用方法

//指定file_id來啟動該檔案的上傳,如果file_id被忽略了,那麼預設開始上傳第一個檔案。
void startUpload(file_id) 
//指定file_id來退出檔案的上傳,從上傳隊列中删除該檔案。
//如果忽略file_id,那麼預設檔案上傳隊列中的第一個檔案将被退出上傳。
//如果取消的檔案是正在上傳,那麼會觸發uploadError事件。
//如果将可選參數trigger_error_event設定為false,那麼uploadError事件不會觸發。
void cancelUpload(file_id, trigger_error_event) 
//如果目前有檔案上傳,那麼停止上傳,并且将檔案還原到上傳隊列中。
//停止了正在上傳的檔案,uploadError事件會被觸發。如果此時沒有正在上傳檔案,那麼不會發生任何操作,不會觸發任何事件。
void stopUpload() 
//擷取目前狀态的統計對象,具體見Stats Object
object getStats() 
Stats Object:{
	in_progress : number // 值為1或0,1表示目前有檔案正在上傳,0表示目前沒有檔案正在上傳
	files_queued : number // 目前上傳隊列中存在的檔案數量
	successful_uploads : number	// 已經上傳成功(uploadSuccess觸發)的檔案數量
	upload_errors : number // 已經上傳失敗的檔案數量 (不包括退出上傳的檔案)
	upload_cancelled : number	// 退出上傳的檔案數量
	queue_errors : number // 入隊失敗(fileQueueError觸發)的檔案數量
}
//動态修改post_params,以前的屬性全部被覆寫。param_object必須是一個JavaScript的基本對象,所有屬性和值都必須是字元串類型。
void setPostParams(param_object)

           

更多詳細的功能請參考SWFUpload V2.2.0 API 說明文檔

繼續閱讀