SWFUpload是一个批量上传插件,在HTML4.1里面,估计也只有Flash+javascript配合才能够做到了。先复制个重要的网址,这个应该是官方的文档了,相当齐全。
http://leeon.me/upload/other/swfupload.html#uploadStart
这个是格式比较好看的。
http://www.cnblogs.com/2050/archive/2012/08/29/2662932.html
算了,这个文档的内容太多,各种属性各种方法,记不了这么多,直接贴上个实例算了。
前台是视图javascript代码:
<script src="@Url.Content("~/Scripts/Swfupload/swfupload.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/Swfupload/handlers.js")" charset="utf-8" type="text/javascript"></script>
<script type="text/javascript"> var swfu; $(function () { swfu = new SWFUpload({ //Backend Settings upload_url: '@Url.Action("AjaxUploadPic")', //网上说一定要是绝对路径 // post_params: { "name": "value", "name": "value" }, //上传时可提交参数 post_params: { "ASPSESSID": "<%=Session.SessionID %>", }, use_query_string: false, // File Upload Settings file_size_limit: "200 MB", //文件最大值 file_types: "*.*", //文件类型, file_types_description: "JPG Images", file_upload_limit: "10", //Zero means unlimited file_queue_limit: "10", //只允许一个文件 //文件上传事件驱动,冒号后边是函数(方法),方法放到 handlers.js 里面了,方便管理。 file_queue_error_handler: fileQueueError, file_dialog_complete_handler: fileDialogComplete, file_queued_handler: fileQueued, upload_progress_handler: uploadProgress, //文件上传过程中定时触发,可用来显示上传进度 upload_error_handler: uploadError, //上传失败触发 upload_success_handler: uploadSuccess, //上传成功触发 upload_complete_handler: uploadComplete, //上传成功和失败都会触发 upload_start_handler: uploadStart, //上传前触发,一般可用来初始化提交参数 //FlashButton settings button_image_url: '@Url.Content("~/Scripts/Swfupload/images/112.jpg")', //flash按钮背景,注意自己的路径。 button_placeholder_id: "spanButtonPlaceholder", //页面存放按钮的容器 button_ 200, button_height: 51, button_text: '<span class="buttonCss"></span>', //按钮文本 button_text_style: ".button { font-family: Helvetica, Arial, sans-serif; font-size: 14pt; } .buttonSmall { font-size: 10pt; }", //按钮文本样式 button_text_top_padding: 1, button_text_left_padding: 5, button_cursor: SWFUpload.CURSOR.HAND, button_action: SWFUpload.BUTTON_ACTION.SELECT_FILES, //多文件上传 单文件上传设置,详细见中文说明,页面有连接 //Flash Settings flash_url: '@Url.Content("~/Scripts/Swfupload/swfupload.swf")', custom_settings: { upload_target: "divFileProgressContainer" }, //Debug Settings debug: false }); }); </script>
handle处理javascript代码:
var fileCount; function fileQueueError(file, errorCode, message) { //alert(file.name + message); try { var imageName = "error.gif"; var errorName = ""; if (errorCode === SWFUpload.errorCode_QUEUE_LIMIT_EXCEEDED) { errorName = "You have attempted to queue too many files."; } 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("images/" + imageName); } catch (ex) { this.debug(ex); } } function fileQueued(file) { try { var progress = new FileProgress(file, this.customSettings.upload_target); progress.setProgress(0); progress.toggleCancel(true, this); } catch (ex) { this.debug(ex); } } function uploadStart(file) { this.addPostParam("bank", $(".in").val()); } function fileDialogComplete(numFilesSelected, numFilesQueued) { try { if (numFilesQueued > 0) { fileCount = numFilesQueued; if ($("#itemId").val() == "") { alert("Please save the basic information First!"); } else { this.addPostParam("itemId", $("#itemId").val()); 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) { progress.toggleCancel(false, this); } else { progress.toggleCancel(true, this); } } catch (ex) { this.debug(ex); } } var imagesCount = -1; function uploadSuccess(file, serverData) { imagesCount++; try { var image = strToJson(serverData); if (image.success == "0") { alert(image.name); } else { $(".album_list li").eq(imagesCount).find("img").attr("src", image.name); } var progress = new FileProgress(file, this.customSettings.upload_target); progress.toggleCancel(false); } catch (ex) { this.debug(ex); } //alert(serverData); } var iCount = 0; function itemUpdateuploadSuccess(file, serverData) { iCount++; var image = strToJson(serverData); if (image.success == "0") { alert(image.name); } else { var dom = $("<li><img src='" + image.name + "' alt='' /></li>"); $(".album_list").append(dom); } if (iCount == fileCount) { alert("upload success!") } var progress = new FileProgress(file, this.customSettings.upload_target); progress.toggleCancel(false); } function strToJson(str) { var json = (new Function("return " + str))(); return json; } function uploadComplete(file) { try { var progress = new FileProgress(file, this.customSettings.upload_target); progress.setComplete(); if (this.getStats().files_queued > 0) { this.startUpload(); } else { 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.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.toggleCancel(true); } catch (ex2) { this.debug(ex2); } case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED: imageName = "uploadlimit.gif"; break; default: alert(message); break; } addImage("images/" + imageName); } catch (ex3) { this.debug(ex3); } } function addImage(src) { var newImg = document.createElement("img"); newImg.style.margin = "5px"; document.getElementById("thumbnails").appendChild(newImg); 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); } } /* ****************************************** * FileProgress Object * Control object for displaying file info * ****************************************** */ function FileProgress(file, targetID) { if (file.filestatus != -5) { this.fileProgressID = file.id; this.fileProgressWrapper = document.getElementById(this.fileProgressID); if (this.fileProgressWrapper == null) { 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.innerHTML = "delete"; var progressText = document.createElement("div"); progressText.className = "progressName"; progressText.appendChild(document.createTextNode(file.name + " (" + (file.size / 1024000).toFixed(2) + " MB)")); var progressBar = document.createElement("div"); progressBar.className = "progressBarInProgress"; var progressStatus = document.createElement("div"); progressStatus.className = "progressBarStatus"; this.fileProgressElement.appendChild(progressText); this.fileProgressElement.appendChild(progressStatus); progressStatus.appendChild(progressBar); this.fileProgressElement.appendChild(progressCancel); 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[1].childNodes[0].className = "progressBarInProgress"; this.fileProgressElement.childNodes[1].childNodes[0].style.width = percentage + "%"; }; FileProgress.prototype.setComplete = function() { this.fileProgressElement.className = "progressContainer blue"; this.fileProgressElement.childNodes[1].childNodes[0].className = "progressBarInProgress"; this.fileProgressElement.childNodes[1].childNodes[0].style.width = "100%"; var progressOk = document.createElement("span"); progressOk.className = "progressOk"; progressOk.innerHTML = "ok"; this.fileProgressWrapper.childNodes[0].appendChild(progressOk); }; FileProgress.prototype.setError = function() { this.fileProgressElement.className = "progressContainer red"; this.fileProgressElement.childNodes[1].childNodes[0].className = "progressBarError"; this.fileProgressElement.childNodes[1].childNodes[0].style.width = ""; }; FileProgress.prototype.setCancelled = function() { this.fileProgressElement.className = "progressContainer"; this.fileProgressElement.childNodes[1].childNodes[0].className = "progressBarError"; this.fileProgressElement.childNodes[1].childNodes[0].style.width = ""; }; //FileProgress.prototype.setStatus = function(status) { // this.fileProgressElement.childNodes[2].innerHTML = status; //}; FileProgress.prototype.toggleCancel = function(show, swfuploadInstance) { this.fileProgressElement.childNodes[2].style.display = show ? "block" : "none"; if (swfuploadInstance) { var fileID = this.fileProgressID; var filePro = this.fileProgressElement.childNodes[2]; filePro.onclick = function() { var f = document.getElementById(fileID); f.parentNode.removeChild(f); swfuploadInstance.cancelUpload(fileID); return false; }; } };
HTML代码:
<div class="album"> <div> <span>会员相册</span> <div style="margin-left:480px;"> <span id="spanButtonPlaceholder" style="margin-left:300px">dddd</span> <input type="button" value="确定上传" style="display:none;" onclick="javascript:swfu.startUpload()" /> <div id="divFileProgressContainer" style="display:none;"></div> </div> <div class="clear"></div> </div> <ul class="album_list"> <li><img src="/Content/CenterImages/upload_image.png" alt="" /></li> <li><img src="/Content/CenterImages/upload_image.png" alt="" /></li> <li><img src="/Content/CenterImages/upload_image.png" alt="" /></li> <li><img src="/Content/CenterImages/upload_image.png" alt="" /></li> <li><img src="/Content/CenterImages/upload_image.png" alt="" /></li> <li><img src="/Content/CenterImages/upload_image.png" alt="" /></li> <li><img src="/Content/CenterImages/upload_image.png" alt="" /></li> <li><img src="/Content/CenterImages/upload_image.png" alt="" /></li> <li><img src="/Content/CenterImages/upload_image.png" alt="" /></li> <li><img src="/Content/CenterImages/upload_image.png" alt="" /></li> </ul> <div class="clear"></div> </div>
控制器代码:
public ActionResult AjaxUploadPic() { PublicCRUD_Respository CRUD = new PublicCRUD_Respository(); HttpPostedFileBase PostedFile = null; PostedFile = HttpContext.Request.Files[0]; string itemId = HttpContext.Request.Form["itemId"]; int ItemId = -1; if (!string.IsNullOrEmpty(itemId)) { ItemId = Convert.ToInt32(itemId); } if(ItemId == -1) { return Content(""); } MariItemInfo Entity = CRUD.SelectById<MariItemInfo>(ItemId); if (Entity.Create.UserId != CurrentUser.UserId) { return Content(""); } object json = null; if (PostedFile != null) { bool success; string result; int count = (int)CRUD.Select_Unique_BySQL("select count(ItemId) from Mari_ItemInfo_Album where itemId = " + ItemId); if (count < 10) { result = UploadFile.SaveFile(PostedFile, UploadFile.PicPath, out success); if (success) { FileInfo fileInfo = new FileInfo(result); //路径存入数据库 if (ItemId != -1) { MariItemInfoAlbum AlbumEntity = new MariItemInfoAlbum(); AlbumEntity.CreateTime = DateTime.Now; AlbumEntity.Pic = UploadFile.UrlConvertor(fileInfo.FullName); AlbumEntity.PicStatus = true; AlbumEntity.PicQuality = 10; MariItemInfo ItemEntity = new MariItemInfo(); ItemEntity.ItemId = ItemId; AlbumEntity.MariItemInfo = ItemEntity; CRUD.Insert<MariItemInfoAlbum>(AlbumEntity); } json = new { success = 1, name = UploadFile.UrlConvertor(fileInfo.FullName) }; } else { json = new { success = 0, name = "图片保存失败" }; } } else { json = new { success = 0, name = "一个用户最多只能上传10张图片!" }; } } else { json = new { success = 0 }; } return Json(json, "text/html", JsonRequestBehavior.AllowGet); }
值得说的是,当页面需要Session验证才能操作的时候在Chrome和火狐浏览器里会上传不了,据说是Session的问题,这个时候可以在Global.asax里面加入下段代码:
protected void Application_Start() { //火狐,谷歌批量上传兼容 Matchmaking.Infrastructure.SwfUploadCompatible.FireFoxCompatible(); AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); }
public static void FireFoxCompatible() { try { string session_param_name = "ASPSESSID"; string session_cookie_name = "ASP.NET_SESSIONID"; if (HttpContext.Current.Request.Form[session_param_name] != null) { UpdateCookie(session_cookie_name, HttpContext.Current.Request.Form[session_param_name]); } else if (HttpContext.Current.Request.QueryString[session_param_name] != null) { UpdateCookie(session_cookie_name, HttpContext.Current.Request.QueryString[session_param_name]); } } catch (Exception) { } } public static void UpdateCookie(string cookie_name, string cookie_value) { HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name); if (cookie == null) { HttpCookie cookie1 = new HttpCookie(cookie_name, cookie_value); System.Web.HttpContext.Current.Response.Cookies.Add(cookie1); } else { cookie.Value = cookie_value; HttpContext.Current.Request.Cookies.Set(cookie); } }
而在前台页面的代码中,加入如下参数选项:
post_params: { "ASPSESSID": "<%=Session.SessionID %>", }