SWFUpload可以说是目前最好的多文件上传工具之一,虽然它是基于flash插件开发的,但是相比目前很多js多文件上传还是具有很多优点:
可以同时选择多个文件上传(注意是以此选择文件)
无刷新上传
可以显示进度条
良好的浏览器兼容性
兼容其他js类库
SWFUpload另个优点就是它优秀的设计,它提供了一组简明的Javascript事件,借助它们开发者可以方便的在文件上传过程中更新页面的内容。
下面是SWFUpload在具体使用过程中js代码
MultiFileHandler.js
function fileQueueError(file,
errorCode, message) { try { var imageName
= "error.gif" ; var errorName
= "" ; if (errorCode
=== SWFUpload.errorCode_QUEUE_LIMIT_EXCEEDED) { errorName
= "文件超过最大上传个数!" ; } if (errorName
!== "" )
{ alert(errorName); return ; } switch (errorCode)
{ case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: imageName
= "zerobyte.gif" ; break ; case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: imageName
= "toobig.gif" ; break ; case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE: default : alert(message); break ; } addImage( "/modules/commons/view/multifileupload/images/" +
imageName); }
catch (ex)
{ this .debug(ex); } } function fileDialogComplete(numFilesSelected,
numFilesQueued) { try { if (numFilesQueued
> 0) { this .startUpload(); } }
catch (ex)
{ this .debug(ex); } } function uploadProgress(file,
bytesLoaded) { try { var percent
= Math.ceil((bytesLoaded / file.size) * 100); var progress
= new FileProgress(file,
this .customSettings.upload_target); progress.setProgress(percent); if (percent
== 100) { if (showThumbnail){ progress.setStatus( "正在创建缩略图..." ); } progress.toggleCancel( false ,
this ); uploadNum++; setUploadNumber(uploadNum); }
else { progress.setStatus( "正在上传中,已完成" +percent+ "%" ); progress.toggleCancel( true ,
this ); } }
catch (ex)
{ this .debug(ex); } } //文件数据发送成功,不管是否成功保存;其serverData是否服务器端处理完以后的返回值 //这里规定返回值必须为success才代表成功 var serverErrorInfo= "" ; function uploadSuccess(file,
serverData) { try { var sd=serverData.replace(/
/gi, '' ).replace(/ /gi, '' ).replace(/\r/gi, '' ).replace(/\n/gi, '' ).replace(/\t/gi, '' ); if (showThumbnail){ var filePath= ".." ; if (savePath!= '' ){ filePath=filePath+ "/" +savePath; } filePath=filePath+ '/' +file.name; addImage(filePath); } var progress
= new FileProgress(file,
this .customSettings.upload_target); if (showThumbnail){ progress.setStatus( "缩略图创建完成!" ); } if (sd!= '' ){ if (sd!= 'success' ){ if (serverErrorInfo!= '' ){ serverErrorInfo+= '<br
/>' ; } serverErrorInfo+=sd; document.getElementById( 'divError' ).innerHTML=serverErrorInfo; } } progress.toggleCancel( false ); }
catch (ex)
{ this .debug(ex); } } //服务器端返回非空值才认为上传成功,触发下面事件 function uploadComplete(file)
{ try { /*
I want the next upload to continue automatically so I'll call startUpload here */ if ( this .getStats().files_queued
> 0) { this .startUpload(); }
else { var progress
= new FileProgress(file,
this .customSettings.upload_target); progress.setComplete(); if (!isCancel){ progress.setStatus( "文件上传成功!" ); } else { progress.setStatus( "上传已取消!" ); isCancel= false ; } progress.toggleCancel( false ); } }
catch (ex)
{ this .debug(ex); } } function uploadError(file,
errorCode, message) { var imageName
= "error.gif" ; var progress; try { switch (errorCode)
{ case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED: try { progress
= new FileProgress(file,
this .customSettings.upload_target); progress.setCancelled(); progress.setStatus( "取消完成!" ); progress.toggleCancel( false ); } catch (ex1)
{ this .debug(ex1); } break ; case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED: try { progress
= new FileProgress(file,
this .customSettings.upload_target); progress.setCancelled(); progress.setStatus( "已停止!" ); progress.toggleCancel( true ); } catch (ex2)
{ this .debug(ex2); } case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED: imageName
= "uploadlimit.gif" ; break ; default : alert(message); break ; } addImage( "/modules/commons/view/multifileupload/images/" +
imageName); }
catch (ex3)
{ this .debug(ex3); } } function addImage(src)
{ var imageName=getFileName(src); var divImage=document.createElement( "span" ); divImage.style.margin
= "5px" ; divImage.style.padding
= "1px" ; divImage.style.width
= "59px" ; divImage.style.height
= "85px" ; divImage.style.display= "block" ; divImage.style.border= "10px" ; divImage.style.float= "left" ; divImage.attachEvent( "onmouseover" ,
setBackground(divImage, "#FFFACD" ));
divImage.attachEvent( "onmouseout" ,
setBackground(divImage, "#FFFFFF" ));
var newImg
= document.createElement( "img" ); //newImg.style.margin
= "5px"; newImg.style.width
= "59px" ; newImg.style.height
= "59px" ; newImg.alt=imageName; var divImageName=document.createElement( "div" ); divImageName.style.marginTop= "5px" ; divImageName.style.width= "59px" ; divImageName.style.height= "20px" ; divImageName.style.textAlign= "center" ; divImageName.innerHTML=imageName; divImage.appendChild(newImg); divImage.appendChild(divImageName); document.getElementById( "thumbnails" ).appendChild(divImage); if (newImg.filters)
{ try { newImg.filters.item( "DXImageTransform.Microsoft.Alpha" ).opacity
= 0; }
catch (e)
{ //
If it is not set initially, the browser will throw an error. This will set it if it is not set yet. newImg.style.filter
= 'progid:DXImageTransform.Microsoft.Alpha(opacity= '
+ 0 + ' ) '; } }
else { newImg.style.opacity
= 0; } newImg.onload
= function () { fadeIn(newImg,
0); }; newImg.src
= src; } function
fadeIn(element, opacity) { var
reduceOpacityBy = 5; var
rate = 30; // 15 fps if
(opacity < 100) { opacity
+= reduceOpacityBy; if
(opacity > 100) { opacity
= 100; } if
(element.filters) { try
{ element.filters.item("DXImageTransform.Microsoft.Alpha").opacity
= opacity; }
catch (e) { //
If it is not set initially, the browser will throw an error. This will set it if it is not set yet. element.style.filter
= ' progid:DXImageTransform.Microsoft.Alpha(opacity= '
+ opacity + ' ) '; } }
else { element.style.opacity
= opacity / 100; } } if
(opacity < 100) { setTimeout(function
() { fadeIn(element,
opacity); },
rate); } } var
isCancel=false;//是否取消上传 var
uploadNum=0;//已成功上传文件 cancelUpload=function(){ document.getElementById(' imgCancelButton ').style.visible=' hidden '; swfu.cancelUpload(); /*var
fileProgressID = "divFileProgress"; var
fileProgressWrapper = document.getElementById(fileProgressID); var
fileProgressElement = fileProgressWrapper.firstChild; fileProgressElement.childNodes[2].innerHTML
= ' 上传已停止! ';*/ isCancel=true; } setUploadNumber=function(num){ document.getElementById("lgdUploadNumber").innerHTML="文件上传(已上传<span
id=' spNumber '>"+num+"</span>个文件)"; } getFileName=function(filePath){ var
i=0; if(filePath.indexOf(' / ')==-1){ i=filePath.lastIndexOf(' \\ '); }else{ i=filePath.lastIndexOf(' / '); } var
j=filePath.lastIndexOf(' .'); var fileName=filePath.substring(i+1,j); return fileName; } setBackground= function (obj,color){ return function (){ setBackgroundWithParams(obj,color); } } setBackgroundWithParams= function (obj,color){ obj.style.backgroundColor=color; obj.style.border= "1px" ; obj.style.borderColor= "red" ; } /*
****************************************** *
FileProgress Object *
Control object for displaying file info *
****************************************** */ function FileProgress(file,
targetID) { this .fileProgressID
= "divFileProgress" ; this .fileProgressWrapper
= document.getElementById( this .fileProgressID); if (! this .fileProgressWrapper)
{ this .fileProgressWrapper
= document.createElement( "div" ); this .fileProgressWrapper.className
= "progressWrapper" ; this .fileProgressWrapper.id
= this .fileProgressID; this .fileProgressElement
= document.createElement( "div" ); this .fileProgressElement.className
= "progressContainer" ; var progressCancel
= document.createElement( "a" ); progressCancel.className
= "progressCancel" ; progressCancel.href
= "#" ; progressCancel.id
= "imgCancelButton" ; progressCancel.attachEvent( "onclick" ,
cancelUpload); progressCancel.style.visibility
= "hidden" ; progressCancel.appendChild(document.createTextNode( "
" )); var progressText
= document.createElement( "div" ); progressText.className
= "progressName" ; progressText.appendChild(document.createTextNode(file.name)); var progressBar
= document.createElement( "div" ); progressBar.className
= "progressBarInProgress" ; var progressStatus
= document.createElement( "div" ); progressStatus.className
= "progressBarStatus" ; progressStatus.innerHTML
= " " ; this .fileProgressElement.appendChild(progressCancel); this .fileProgressElement.appendChild(progressText); this .fileProgressElement.appendChild(progressStatus); this .fileProgressElement.appendChild(progressBar); this .fileProgressWrapper.appendChild( this .fileProgressElement); document.getElementById(targetID).appendChild( this .fileProgressWrapper); fadeIn( this .fileProgressWrapper,
0); }
else { this .fileProgressElement
= this .fileProgressWrapper.firstChild; this .fileProgressElement.childNodes[1].firstChild.nodeValue
= file.name; } this .height
= this .fileProgressWrapper.offsetHeight; } FileProgress.prototype.setProgress
= function (percentage)
{ this .fileProgressElement.className
= "progressContainer
green" ; this .fileProgressElement.childNodes[3].className
= "progressBarInProgress" ; this .fileProgressElement.childNodes[3].style.width
= percentage + "%" ; }; FileProgress.prototype.setComplete
= function ()
{ this .fileProgressElement.className
= "progressContainer
blue" ; this .fileProgressElement.childNodes[3].className
= "progressBarComplete" ; this .fileProgressElement.childNodes[3].style.width
= "" ; }; FileProgress.prototype.setError
= function ()
{ this .fileProgressElement.className
= "progressContainer
red" ; this .fileProgressElement.childNodes[3].className
= "progressBarError" ; this .fileProgressElement.childNodes[3].style.width
= "" ; }; FileProgress.prototype.setCancelled
= function ()
{ this .fileProgressElement.className
= "progressContainer" ; this .fileProgressElement.childNodes[3].className
= "progressBarError" ; this .fileProgressElement.childNodes[3].style.width
= "" ; }; FileProgress.prototype.setStatus
= function (status)
{ this .fileProgressElement.childNodes[2].innerHTML
= status; }; FileProgress.prototype.toggleCancel
= function (show,
swfuploadInstance) { this .fileProgressElement.childNodes[0].style.visibility
= show ? "visible" :
"hidden" ; if (swfuploadInstance)
{ var fileID
= this .fileProgressID; this .fileProgressElement.childNodes[0].onclick
= function ()
{ swfuploadInstance.cancelUpload(fileID); return false ; }; } }; |
MultiFileUpload.js
var uploadUrl= '$!{request.uploadUrl}' ; //上传处理的url var savePath= '$!{request.savePath}' ; var fileType= '$!{request.fileType}' ; //var
postName='$request.postName'; var sizeLimit= '$!{request.sizeLimit}' ; var uploadLimit= '$!{request.uploadLimit}' ; //var
buttonWidth='$!{request.buttonWidth}'; //var
buttonHeight='$!{request.buttonHeight}'; var buttonText= '$!{request.buttonText}' ; var buttonAlign= '$!{request.buttonAlign}' ; var componentHeight= '$!{request.componentHeight}' ; var showThumbnail= '$!{request.showThumbnail}' ;
//是否显示缩略图,一般用于图片上传,默认为false var thumbnailScroll= '$!{request.thumbnailScroll}' ; //缩略图部分是否显示滚动条 if (uploadUrl== '' ){ //uploadUrl='/Commons/fileUpload.do'; uploadUrl= '/commons/paste.do?template=/multifileupload/data/upload.htm' ; } //if(postName=''){ //
postName= "Filedata"; //} if (fileType== '' ){ fileType= '*.*' ; } if (uploadLimit== '' ){ uploadLimit=0; } //if(buttonWidth==''){ //
buttonWidth=100; //} //if(buttonHeight==''){ //
buttonHeight=22; //} if (buttonText== '' ){ buttonText= '选
择 文 件' ; } if (buttonAlign== '' ){ buttonAlign= 'left' ; } if (showThumbnail== '' ){ showThumbnail= false ; } else { showThumbnail= true ; } if (thumbnailScroll== '' ){ thumbnailScroll= false ; } else { thumbnailScroll= true ; } if (uploadUrl.indexOf( '?' )!=-1){ uploadUrl=uploadUrl+ '&savePath=' +encodeURIComponent(savePath); } else { uploadUrl=uploadUrl+ '?savePath=' +encodeURIComponent(savePath); } var swfu; window.onload
= function ()
{ swfu
= new SWFUpload({ upload_url:
uploadUrl, file_size_limit
: sizeLimit, file_types
: fileType, //file_types_description
: "JPG Images", file_upload_limit
: uploadLimit, //
Zero means unlimited file_queue_error_handler
: fileQueueError, file_dialog_complete_handler
: fileDialogComplete, upload_progress_handler
: uploadProgress, upload_error_handler
: uploadError, upload_success_handler
: uploadSuccess, upload_complete_handler
: uploadComplete, button_image_url
: "/modules/commons/view/multifileupload/images/XPButtonNoText_160x22.png" , button_placeholder_id
: "spanButtonPlaceholder" , button_width:
101, button_height:
22, button_text
: buttonText, button_text_style
: '.button
{ font-family: 华文行楷,宋体, Arial, sans-serif; font-size: 14pt; } .buttonSmall { font-size: 10pt; }' , button_text_top_padding:
1, button_text_left_padding:
20, flash_url
: "/modules/commons/js/swfupload/swfupload.swf" , custom_settings
: { upload_target
: "divFileProgressContainer" }, debug:
false }); if (thumbnailScroll){ var divThumbnails=document.getElementById( "thumbnails" ); var divContent=document.getElementById( "content" ); divContent.style.width= "400px" ; divThumbnails.style.height= '200px' ; divThumbnails.style.overflowY= "scroll" ; divThumbnails.style.border= "solid
1px #DDF0DD" ; } document.getElementById( "divButtonPlaceholder" ).style.textAlign=buttonAlign; if (componentHeight!= '' ){ componentHeight=componentHeight.replace( "px" , "" ); componentHeight=Number(componentHeight)-25; //去掉空隙和按钮高度 document.getElementById( "fsProgress" ).style.height=componentHeight+ "px" ; } } |
其中MultiFileHandler.js是对于上传过程中各个事件的处理,MultiFileUpload.js是SWFUpload的使用,"$"符号开头的变量在实际使用过程中可以自由定制,另外在此还要提醒大家,。代码中的savePath变量是文件最后的保存路径,后台只要读取此变量保存到相应的位置即可。下面是后台代码:
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; namespace WebApplication1 { public partial class FileUpload
: System.Web.UI.Page { protected void Page_Load( object sender,
EventArgs e) { string path= "" ; HttpPostedFile
file= Request.Files[ "FileData" ]; string relationPath=Request[ "savePath" ]; if (relationPath!= string .Empty) { path=Server.MapPath( "~/" )+relationPath+ "\\" +file.FileName; } file.SaveAs(path); Response.Write( "success" ); } } } |
需要注意的是在后台一定要给出返回值(例如上面代码中Response.Write("success"))否则SWFUpload就不认为是上传完成。
下面的实际效果: