說在前面
最近在做一個MVC相冊的網站(這里),需要批量上傳照片功能,所以就在網上搜相關的插件,偶然機會發現Dropzone.js,試用了一下完全符合我的要求,而且樣式挺滿意的,於是就在我的項目中使用了這個插件。在使用的過程中發現中文的相關文檔較少,說多了都是淚,硬着頭皮看官方的網站,本來英文不咋地,只能邊查單詞邊用了,於是就有了這篇文章,主要是總結在使用Dropzone中的遇到的一些問題及詳細的使用步驟。
Dropzone.js是啥?
Dropzone.js是一個開源庫,提供拖放文件上傳及圖像預覽。它是輕量級的,不依賴於任何其他庫(如jQuery),並且是高度可定制的,官網在這里。首先說在前面的是因為這是一個基於Html APIs的插件,所以有下列瀏覽器支持:
- Chrome 7+
- Firefox 4+
- IE 10+
- Opera 12+ (Version 12 for MacOS is disabled because their API is buggy)
- Safari 6+
注意:如果您的客戶還在使用IE10以下的瀏覽器,那可能這篇文章不太適合您,或者您可以說服客戶放棄使用IE,可能獲得不一樣的體驗。
效果圖
直接上幾張效果圖,大家先看看是否符合您的要求,再決定是否使用。
如何下載?
官網提供的js下載,在這里,這僅僅是一個js,不包括相關的樣式、圖片等,所以建議從Github上下載完整的包,地址在這里。下載這個項目最簡單的方法是使用右側的Download ZIP,會自動將所有文件打包成zip格式的文件下載下來,里面的downloads文件夾就是我們需要的,包括需要用到的js、圖片、css等文件。
如何使用?
dropzone官網提供了Demo,但是Demo中沒有實現一次上傳多張圖片的功能,而且也沒有提供服務器端C#的相關代碼。所以我就把使用的步驟總結了一下,方便以后的復用。在這里我把使用方法分為前端和后端的代碼,前端主要是文件的引用、dropzone初始化、以及相關的屬性事件說明。后端就是指MVC中Action了,主要功能是從Request獲取文件,存放到服務器中。下面讓我細細道來。
★前端
1、引用文件
首先呢,肯定是先把下載的文件分類放到自己的項目中,這樣便於以后的管理,也符合國際慣例。
然后就需要在頁面中引用,引用的代碼如下:
//樣式文件 <link href="~/Content/css/dropzone.css" rel="stylesheet" /> //jQuery文件,不是必需的 <script src="~/Scripts/jquery-1.8.2.min.js"></script> //js文件 <script src="~/Scripts/dropzone.js"></script>
大家看到我引用了三個文件,其中jQuery的文件不是必需的,因為在文章開頭也介紹過dropzone是獨立的庫,不需要依賴jQuery,我為了操作方便,所以在這里引用了一下,看個人選擇了。
2、建立表單元素
<!--class="dropzone" 使用dropzone自帶的樣式 樣式在引用的CSS中--> <form action="/" class="dropzone" enctype="multipart/form-data" id="my-dropzone" method="post"> <!--上傳圖片時,需要同時提交的數據,這里做個演示--> @Html.Hidden("hidAlbumId") </form> <div> <!--上傳按鈕,提供多張圖片一次性上傳的功能--> <button type="submit" id="submit-all" disabled="disabled">上傳</button> </div>
3、初始化Dropzone,並添加屬性和事件
<script> //Dropzone的初始化,myDropzone為form的id Dropzone.options.myDropzone = { //指定上傳圖片的路徑 url: "@Url.Action("BatchUpload", "PhotoUpload")", //添加上傳取消和刪除預覽圖片的鏈接,默認不添加 addRemoveLinks: true, //關閉自動上傳功能,默認會true會自動上傳 //也就是添加一張圖片向服務器發送一次請求 autoProcessQueue: false, //允許上傳多個照片 uploadMultiple: true, //每次上傳的最多文件數,經測試默認為2,坑啊 //記得修改web.config 限制上傳文件大小的節 parallelUploads: 100, init: function () { var submitButton = document.querySelector("#submit-all") myDropzone = this; // closure //為上傳按鈕添加點擊事件 submitButton.addEventListener("click", function () { //手動上傳所有圖片 myDropzone.processQueue(); }); //當添加圖片后的事件,上傳按鈕恢復可用 this.on("addedfile", function () { $("#submit-all").removeAttr("disabled"); }); //當上傳完成后的事件,接受的數據為JSON格式 this.on("complete", function (data) { if (this.getUploadingFiles().length === 0 && this.getQueuedFiles().length === 0) { var res = eval('(' + data.xhr.responseText + ')'); var msg; if (res.Result) { msg = "恭喜,已成功上傳" + res.Count + "張照片!"; } else { msg = "上傳失敗,失敗的原因是:" + res.Message; } $("#message").text(msg); $("#dialog").dialog("open"); } }); //刪除圖片的事件,當上傳的圖片為空時,使上傳按鈕不可用狀態 this.on("removedfile", function () { if (this.getAcceptedFiles().length === 0) { $("#submit-all").attr("disabled", true); } }); } }; </script>
這樣前端的工作基本完成了,下面來看看后端的工作。
★后端
后端的功能挺簡單,就是接收文件,然后將數據保存到服務器上,並返回JSON數據。代碼如下:
[HttpPost] public ActionResult BatchUpload() { bool isSavedSuccessfully = true; int count = 0; string msg = ""; string fileName = ""; string fileExtension = ""; string filePath = ""; string fileNewName = ""; //這里是獲取隱藏域中的數據 //int albumId = string.IsNullOrEmpty(Request.Params["hidAlbumId"]) ? // 0 : int.Parse(Request.Params["hidAlbumId"]); try { string directoryPath = Server.MapPath("~/Content/photos"); if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath); foreach (string f in Request.Files) { HttpPostedFileBase file = Request.Files[f]; if (file != null && file.ContentLength > 0) { fileName = file.FileName; fileExtension = Path.GetExtension(fileName); fileNewName = Guid.NewGuid().ToString() + fileExtension; filePath = Path.Combine(directoryPath, fileNewName); file.SaveAs(filePath); count++; } } } catch (Exception ex) { msg = ex.Message; isSavedSuccessfully = false; } return Json(new { Result = isSavedSuccessfully, Count = count, Message = msg }); }
總結
通過這次實踐,剛發現Html APIs的強大,Dropzone就是通過調用APIs實現的功能,現在自己的技術從各個方面來說已經落后很多了,以后得抓緊自己的業余時間,多做些個人項目,才能在實踐中不斷提高。由於自己對相關技術理解不深,文中必有疏漏,還請大家批評指正。
參考
http://www.dropzonejs.com/bootstrap.html
http://stackoverflow.com/questions/18048825/how-to-limit-the-number-of-dropzone-js-files-uploaded
http://venkatbaggu.com/file-upload-in-asp-net-mvc-using-dropzone-js-and-html5/
http://stackoverflow.com/questions/16050965/using-dropzone-js-in-asp-net
https://github.com/enyo/dropzone/wiki/Upload-all-files-with-a-button