最近,在後臺實現廣告管理系統,有一個表單選項,想利用SWFUpload組件來實現。如今將該組件的認識和理解記錄以下:方便有須要的同行查看.html
1、首先來比較下目前的幾種的客戶端上傳:瀏覽器
一、File表單網絡
使用標準的HTML元素提供的File表單是最原始、傳統的上傳方式,他的優點在於瀏覽器的普遍兼容性,除了服務端須要處理Files信息之外,不須要額外的處理程序便可完成文件上傳。多線程
但使用File表單上傳文件會形成頁面的刷新,尤爲是在上傳大文件的時候,在文件上傳過程當中,用戶須要傻等在一個空白頁面前,沒有任何反饋信息來提示用戶當前的上傳進度。同時沒法在客戶端對文件大小作檢測。異步
二、IFrame結合File表單網站
使 用一個含有file表單的iframe來完成文件上傳,可以避免文件上傳過程當中的頁面刷新,在必定程度上改進了用戶體驗,但一樣沒有解決大文件上 傳時候缺乏反饋信息的問題。相比File表單上傳,此方式還須要對程序作額外的處理,同時須要JS的支持,複雜度稍微增長了一些。url
三、IFrame、File表單結合AJAX線程
在方式2的基礎上引入AJAX來實時跟服務端腳本獲取當前的上傳進度,實現了頁面無刷新、實時更新上傳進度的功能。但程序的複雜度又增長了一個級別,因爲要不斷跟服務端發送請求,同時也增長了服務端的壓力。翻譯
四、Activex控件orm
使用控件方式完成的上傳在功能和效率上都很不錯,頁面無刷新、顯示上傳進度、批量上傳,我的認爲遺憾就在於須要在瀏覽器上安裝控件,並且只能支持IE,彈出那麼個安裝提示可能會嚇倒多數用戶,開發的複雜度也提升了。
五、Flash
Flash的FileReference類提供了文件上傳功能,相對於傳統的File表單而言,Flash上傳可以獲取客戶端的文件的更多信息反饋,例如文件大小、類型、建立、修改時間等,利用這些信息能夠在客戶端對文件進行類型和大小等屬性的一次過濾。
FileReference類提供了多文件上傳功能。
Flash直接向服務端發送文件數據,所以Flash自己是能夠隨時知道文件上傳數據而顯示上傳進度,而不須要使用AJAX的方式不斷跟服務端發送請求增長服務端的壓力。
弊端在於客戶端須要Flash播放器的支持,並且在一個頁面中插入一個Flash,從UI元素的統一角度來看,彷佛有些彆扭,若是頁面須要更改風格,那麼Flash還須要從新修改而後編譯,並且程序開發的複雜度也提升了。
六、Flash結合JavaScript
在方式5的基礎上,將Flash隱藏起來,利用JavaScript來控制Flash元素處理文件上傳,Flash使用 ExternalInterface來完成跟JavaScript的通訊,將頁面元素的控制權交給JS。這樣就避免了方式5中的UI元素不統1、修改不靈 活的弊端。但代價就是Flash程序開發的複雜度再次提升了,同時也須要更高的JS和XHTML開發能力。
以 上列舉了目前我所瞭解的瀏覽器環境下文件上傳的方式,並對其優劣都作了簡單的羅列,在實際開發中咱們能夠根據本身的應用來選擇合適的方式,假如我 們的需求只是用戶給本身上傳一個10K不到的頭像,若是咱們還大費周折地實現了頭像上傳的進度提示,那就是事倍功半了,由於在目前的絕大多數網絡狀況下, 一個10K的文件傳輸是一眨眼的功夫。
2、關於SWFUpload
若是項目中在瀏覽器環 境下須要高級上傳功能,那麼我我的認爲使用方式6是最合適的選擇,而SWFUpload在很大程度上下降了開發的複雜度,它提 供了一個編譯好的不包含任何UI元素的Flash影片,並將瀏覽器的中UI交給開發人員來控制。開發人員可以利用 XHTML,CSS,Javascript來定製符合他們網站風格的UI上傳元素。而後使用它提供的一組簡單的JS事件來更新上傳狀態,開發人員可以利用 這些事件來及時更新頁面中的上傳進度UI,針對錯誤、異常等給用戶反饋。
關於SWFUpload的使用,我已經將官方文檔結合本身使用的關鍵點作了一個翻譯和備註,可見SWFUpload翻譯,網上也常常有朋友問我要例子演示,實際上官方的demo就是很好的例子,本身下載下來仔細看看問題不大的。這裏我只是想針對一些朋友問起過的問題的誤區來回答下SWFUpload不能作什麼。
一、它不能在服務端寫文件
你 能夠把SWFUpload理解成是一個功能更強大一點的file表單,它的能力範圍僅僅在客戶端做用,它只能往upload_url對應的服務端 程序發送文件數據,並不能本身自動在服務端寫一個文件。所以upload_url對應的服務端程序須要跟接收傳統的File表單信息同樣接收Flash傳 遞過來的文件信息,而後根據本身需求完成該文件的存儲。
二、它不能保留原有的Session進程
SWFUpload在上傳時至關於從新開闢了一個新的Session進程,所以沒法與原有程序的Session保持一致,這就形成了你沒法像傳統的表單上傳那樣訪問客戶端標識。
若是你須要這個客戶端標識,那麼就須要額外程序處理了。你能夠在發送文件信息以前,利用JS將獲取的Cookie信息寫入到SWFUpload的配置中,若是你使用的是FLASH9版本,你還能夠把這個信息寫入到POST變量中一同發送。
或者在頁面初始化SWFUpload實例的時候,能夠直接將客戶端標識寫入在設置中(例如,在upload_url中增長客戶端標識),無需隨後使用JS來增長標識。
三、在選擇文件的時候,它不會讓超出文件大小限制的文件不可見
假如你設置的是容許用戶上傳3M如下的JPG圖片,那麼當用戶打開文件選擇對話框時,他只能看到系統中的文件夾和JPG圖片,類型過濾是有效的,但大小過濾無效,也就是說你看到的文件並不是都是3M如下的。
實際上文件大小的過濾是在文件入隊的時候進行的,若是你選擇的是一個5M的文件加入隊列,那麼會觸發一個QueueError事件來提示你該文件沒有經過過濾檢測。
四、即便你用的是Flash9版本,它也不能自動把你的表單一塊兒自動提交到服務端
AS3中新的URLRequest對象讓文件上傳的時候能夠一同發送POST變量,但這一過程並非自動的,所以當你上傳文件的時候,SWFUpload尚未智能到自動識別你的Form中的全部表單元素,並把他們一塊兒POST到服務端。
若是你確實有這個需求,那麼在上傳前,你可使用JS將目標表單的name和value構形成值對,而後使用addPostParam或者addFileParam方法來設置POST變量跟文件一同提交到服務端。
若是不想採起這種方式,那麼還有個省力的方式。你能夠先上傳文件,當該文件上傳完成之後利用JS來提交Form表單,由服務端邏輯來完成這兩次「異步」提交數據的關聯性,該實現方式的過程跟IFrame結合File表單實現異步上傳相同。
五、它不能自動完成多文件上傳
SWFUpload 提供文件多選功能,但並無提供多文件自動上傳功能。多選的文件都會插入到上傳的文件隊列中,若是你要完成多文件上傳,那麼能夠 在uploadComplete事件的回調中調用startUpload方法來啓動下一個文件的上傳。如此進行下去,直到整個文件隊列中的文件所有自動上 傳完成,整個上傳纔會中止。
六、它不能真正限制用戶上傳的文件數量
設置中的file_upload_limit只是針對當前頁面中的一個SWFUpload實例有效,當頁面刷新,該值就被恢復重置了。它並不能記住先前的上傳數量。若是你須要嚴格限制用戶上傳的文件數量,那麼就須要經過服務端邏輯來實現。
七、它不是「多線程」的,一個時間點只能上傳一個文件
SWFUpload雖然能完成多文件上傳,但它是「單線程」的,當此刻有文件上傳的時候,沒法啓動下一個文件上傳,必須等待當前文件上傳結束(退出、中止、上傳完畢)。