本人在2010年時使用swfupload爲核心進行文件的批量上傳的解決方案。見文章:WEB版一次選擇多個文件進行批量上傳(swfupload)的解決方案。javascript
本人在2013年時使用plupload爲核心進行文件的批量上傳的解決方案。見文章:WEB版一次選擇多個文件進行批量上傳(Plupload)的解決方案 css
最近在學習百度的開源上傳組件WebUploader,寫了一些示例以記錄。WebUploader的缺點是沒有一個比較好的現成的界面,這個界面須要本身去實現。自由度高了一些。html
WebUploader是由Baidu WebFE(FEX)團隊開發的一個簡單的以HTML5爲主,FLASH爲輔的現代文件上傳組件。在現代的瀏覽器裏面能充分發揮HTML5的優點,同時又不摒棄主流IE瀏覽器,沿用原來的FLASH運行時,兼容IE6+,iOS 6+, android 4+。兩套運行時,一樣的調用方式,可供用戶任意選用。前端
關於WebUploader的功能說明:java
分片與併發結合,將一個大文件分割成多塊,併發上傳,極大地提升大文件的上傳速度。jquery
當網絡問題致使傳輸錯誤時,只須要重傳出錯分片,而不是整個文件。另外分片傳輸可以更加實時的跟蹤上傳進度。android
支持經常使用圖片格式jpg,jpeg,gif,bmp,png預覽與壓縮,節省網絡數據傳輸。web
解析jpeg中的meta信息,對於各類orientation作了正確的處理,同時壓縮後上傳保留圖片的全部原始meta數據。ajax
支持文件多選,類型過濾,拖拽(文件&文件夾),圖片粘貼功能。算法
粘貼功能主要體如今當有圖片數據在剪切板中時(截屏工具如QQ(Ctrl + ALT + A), 網頁中右擊圖片點擊複製),Ctrl + V即可添加此圖片文件。
兼容主流瀏覽器,接口一致,實現了兩套運行時支持,用戶無需關心內部用了什麼內核。
同時Flash部分沒有作任何UI相關的工做,方便不關心flash的用戶擴展和自定義業務需求。
當文件體積大、量比較多時,支持上傳前作文件md5值驗證,一致則可直接跳過。
若是服務端與前端統一修改算法,取段md5,可大大提高驗證性能,耗時在20ms左右。
採用可拆分機制, 將各個功能獨立成了小組件,可自由搭配。
採用AMD規範組織代碼,清晰明瞭,方便高級玩家擴展。
一: 下面就是利用WebUploader組件,讓客戶一次選擇多個文件,而後將選擇的文件上傳到服務器的批量文件解決方案。
讓咱們先來看看客戶端的界面效果圖。(多選文件,批量上傳,上傳進度顯示)
1) 顯示界面:
圖1
2) 進行多文件選擇:
圖2
3) 上傳進度顯示
圖3
圖4
說明:見上圖WebUploader默認是3個線程一塊兒併發上傳文件。若是須要增長併發數,或是減小併發數。能夠修改threads屬性,這個屬性就是容許的最大上傳併發數。
3) 上傳成功顯示
圖5
二:具體的代碼與操做步驟:
第一步,要完成下面的示例,必須先準備好WebUploader組件。
1) WebUploader:你們能夠訪問WebUploader官方網站:http://fex.baidu.com/webuploader/download.html,在這個網站上能夠下載到組件與demo。
第二步,這個示例的目錄結構如圖:
1.主要目錄結構
2. 此示例中用到的js腳本文件與css文件。
第三步,前臺部分準備客戶操做的WEB界面,以下[WebUploaderFileByBaidu2.aspx、UploaderFileByBaidu.ashx]
1) 前臺客戶端代碼,其中WebUploaderFileByBaidu2.aspx的代碼以下,WebUploaderFileByBaidu2.aspx.cs文件中只使用默認的代碼,不用添加任何代碼。
Html代碼
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebUploaderFileByBaidu2.aspx.cs" Inherits="WebApplication1.WebUploaderFileByBaidu2" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>WebUploader文件上傳示例</title> <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.2.min.js"></script> <link href="Scripts/webuploader/webuploader.css" rel="stylesheet" /> <script type="text/javascript" src="Scripts/webuploader/webuploader.min.js"></script> <link href="https://cdn.bootcss.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"/> <link href="Scripts/style.css" rel="stylesheet" /> <link href="Scripts/demo.css" rel="stylesheet" /> <link href="Scripts/font-awesome.css" rel="stylesheet" /> <script type="text/javascript"> var applicationPath = window.applicationPath === "" ? "" : window.applicationPath || "../../"; // 文件上傳 jQuery(function () { var $ = jQuery, $list = $('#fileList'), $btn = $('#ctlBtn'), state = 'pending', uploader; uploader = WebUploader.create({ // 不壓縮image resize: false, // swf文件路徑 swf: applicationPath + 'Script/webuploader/Uploader.swf', // 文件接收服務端。 server: 'UploaderFileByBaidu.ashx', // 選擇文件的按鈕。可選。 // 內部根據當前運行是建立,多是input元素,也多是flash. pick: '#picker' }); // 當有文件添加進來的時候 uploader.on('fileQueued', function (file) { $list.append('<div id="' + file.id + '" class="item">' + '<h4 class="info">' + file.name + '</h4>' + '<p class="state">等待上傳...</p>' + '</div>'); }); // 文件上傳過程當中建立進度條實時顯示。 uploader.on('uploadProgress', function (file, percentage) { var $li = $('#' + file.id), $percent = $li.find('.progress .progress-bar'); // 避免重複建立 if (!$percent.length) { $percent = $('<div class="progress progress-striped active">' + '<div class="progress-bar" role="progressbar" style="width: 0%">' + '</div>' + '</div>').appendTo($li).find('.progress-bar'); } $li.find('p.state').text('上傳中'); $percent.css('width', percentage * 100 + '%'); }); uploader.on('uploadSuccess', function (file) { $('#' + file.id).find('p.state').text('已上傳'); }); uploader.on('uploadError', function (file) { $('#' + file.id).find('p.state').text('上傳出錯'); }); uploader.on('uploadComplete', function (file) { $('#' + file.id).find('.progress').fadeOut(); }); uploader.on('all', function (type) { if (type === 'startUpload') { state = 'uploading'; } else if (type === 'stopUpload') { state = 'paused'; } else if (type === 'uploadFinished') { state = 'done'; } if (state === 'uploading') { $btn.text('暫停上傳'); } else { $btn.text('開始上傳'); } }); $btn.on('click', function () { if (state === 'uploading') { uploader.stop(); } else { uploader.upload(); } }); }); </script> </head> <body> <div class="container-fluid"> <div class="col-md-10"> <div class="row">文件上傳示例:</div> <div class="row"> <div id="uploader" class="wu-example"> <!--用來存放文件信息--> <div id="fileList" class="uploader-list"></div> <div class="btns"> <div id="picker" class="btn btn-primary">選擇文件</div> </div> </div> </div> <div class="row"> </div> <div class="row"> <button id="ctlBtn" class="btn btn-default">開始上傳</button></div> </div> <div> </div> </div> </body> </html>
以上代碼最後的顯示結果以下圖:
圖8.
2) 接收前端用戶上傳的文件,並把文件保存到指定目錄中。UploaderFileByBaidu.ashx文件中使用默認的代碼,不須要添加任何代碼。UploaderFileByBaidu.ashx.cs文件的代碼以下:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Web; namespace WebApplication1 { /// <summary> /// UploaderFileByBaidu 的摘要說明 /// </summary> public class UploaderFileByBaidu : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentEncoding = Encoding.UTF8; if (context.Request["REQUEST_METHOD"] == "OPTIONS")
{ context.Response.End(); } SaveFile(); } /// <summary> /// 文件保存操做 /// </summary> /// <param name="basePath"></param> private void SaveFile(string basePath = "~/Upload/Images/") { basePath = FileHelper.GetUploadPath(); string Datedir = DateTime.Now.ToString("yy-MM-dd"); string updir = basePath + "\\" + Datedir; string extname = string.Empty; string fullname = string.Empty; string filename = string.Empty; HttpFileCollection files = System.Web.HttpContext.Current.Request.Files; if (files.Count == 0) { var result = "{\"jsonrpc\" : \"2.0\", \"error\" : \"保存失敗\",\"id\" : \"id\"}"; System.Web.HttpContext.Current.Response.Write(result); } if (!Directory.Exists(updir)) Directory.CreateDirectory(updir); var suffix = files[0].ContentType.Split('/'); var _suffix = suffix[1].Equals("jpeg", StringComparison.CurrentCultureIgnoreCase) ? "" : suffix[1]; var _temp = System.Web.HttpContext.Current.Request["name"]; if (!string.IsNullOrEmpty(_temp)) { filename = _temp; } else { Random rand = new Random(24 * (int)DateTime.Now.Ticks); filename = rand.Next() + "." + _suffix; } fullname = string.Format("{0}\\{1}",updir , filename); files[0].SaveAs(fullname); var _result = "{\"jsonrpc\" : \"2.0\", \"result\" : null, \"id\" : \"" + filename + "\"}"; System.Web.HttpContext.Current.Response.Write(_result); } public bool IsReusable { get { return false; } } } }
第四步:文件輔助類
/// <summary> ///FileHelper 的摘要說明 /// </summary> public class FileHelper { public FileHelper() { // //TODO: 在此處添加構造函數邏輯 // } /// <summary> /// 獲取上傳目錄 /// </summary> /// <returns></returns> public static string GetUploadPath() { string path = HttpContext.Current.Server.MapPath("~/"); string dirname = GetDirName(); string uploadDir = path + "\\" + dirname; CreateDir(uploadDir); return uploadDir; } /// <summary> /// 獲取臨時目錄 /// </summary> /// <returns></returns> public static string GetTempPath() { string path = HttpContext.Current.Server.MapPath("~/"); string dirname = GetTempDirName(); string uploadDir = path + "\\" + dirname; CreateDir(uploadDir); return uploadDir; } private static string GetDirName() { return System.Configuration.ConfigurationManager.AppSettings["uploaddir"]; } private static string GetTempDirName() { return System.Configuration.ConfigurationManager.AppSettings["tempdir"]; } public static void CreateDir(string path) { if (!System.IO.Directory.Exists(path)) { System.IO.Directory.CreateDirectory(path); } } }
第五步,Web.config文件配置信息。
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> </configSections> <appSettings> <add key="uploaddir" value="upload" /> <add key="tempdir" value="temp" /> </appSettings> <system.web> <compilation debug="true" targetFramework="4.0" /> <authentication mode="Windows" /> <httpRuntime maxRequestLength="2147483647" appRequestQueueLimit="1200" executionTimeout="1200"/> <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" /> </system.web> <system.webServer> <security> <requestFiltering > <requestLimits maxAllowedContentLength="2147483647" ></requestLimits> </requestFiltering> </security> </system.webServer> </configuration>
第六步,在進行上傳以後,文件保存在對應的日期目錄下。以下圖。
圖 9