Html5 js上傳外掛程式resumable.js 的使用

來源:互聯網
上載者:User

標籤:

  最近做一個csv檔案上傳,網上找了幾個,相容性不好,年代也比較久遠,就去github上看看找找,發現了一個resumable.js,支援分區上傳,多檔案上傳,完全滿足需求~項目地址:https://github.com/23/resumable.js。

  簡單說下應用,順便儲存下代碼,萬一哪天再用了,忘了還得重新找.....這才是關鍵。

  後台代碼,兩個檔案,一個model,一個webapi,基於C#的。

  model代碼:

namespace Resumable.Models{public class ResumableConfiguration{/// <summary>/// Gets or sets number of expected chunks in this upload./// </summary>public int Chunks { get; set; }/// <summary>/// Gets or sets unique identifier for current upload./// </summary>public string Identifier { get; set; }/// <summary>/// Gets or sets file name./// </summary>public string FileName { get; set; }public ResumableConfiguration(){}/// <summary>/// Creates an object with file upload configuration./// </summary>/// <param name="identifier">Upload unique identifier.</param>/// <param name="filename">File name.</param>/// <param name="chunks">Number of file chunks.</param>/// <returns>File upload configuration.</returns>public static ResumableConfiguration Create(string identifier, string filename, int chunks){return new ResumableConfiguration { Identifier = identifier, FileName = filename, Chunks = chunks };}}}

  API代碼:

using Resumable.Models;using System;using System.IO;using System.Net;using System.Net.Http;using System.Threading.Tasks;using System.Web.Http;namespace Resumable.Controllers{[RoutePrefix("api/File")]public class FileUploadController : ApiController{private string root = System.Web.Hosting.HostingEnvironment.MapPath("~/upload"); [Route("Upload"), HttpOptions]public object UploadFileOptions(){return Request.CreateResponse(HttpStatusCode.OK);}[Route("Upload"), HttpGet]public object Upload(int resumableChunkNumber, string resumableIdentifier){return ChunkIsHere(resumableChunkNumber, resumableIdentifier) ? Request.CreateResponse(HttpStatusCode.OK) : Request.CreateResponse(HttpStatusCode.NoContent);}[Route("Upload"), HttpPost]public async Task<object> Upload(){// Check if the request contains multipart/form-data.if (!Request.Content.IsMimeMultipartContent()){throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);}if (!Directory.Exists(root)) Directory.CreateDirectory(root);var provider = new MultipartFormDataStreamProvider(root);if (await readPart(provider)){// Successreturn Request.CreateResponse(HttpStatusCode.OK);}else{// Failvar message = DeleteInvalidChunkData(provider) ? "Cannot read multi part file data." : "Cannot delete temporary file chunk data.";return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, new System.Exception(message));}}private static bool DeleteInvalidChunkData(MultipartFormDataStreamProvider provider){try{var localFileName = provider.FileData[0].LocalFileName;if (File.Exists(localFileName)){File.Delete(localFileName);}return true;}catch {return false;}}private async Task<bool> readPart(MultipartFormDataStreamProvider provider){try{await Request.Content.ReadAsMultipartAsync(provider);ResumableConfiguration configuration = GetUploadConfiguration(provider);int chunkNumber = GetChunkNumber(provider);// Rename generated fileMultipartFileData chunk = provider.FileData[0]; // Only one file in multipart messageRenameChunk(chunk, chunkNumber, configuration.Identifier);// Assemble chunks into single file if they‘re all hereTryAssembleFile(configuration);return true;}catch {return false;}}#region Get configuration[NonAction]private ResumableConfiguration GetUploadConfiguration(MultipartFormDataStreamProvider provider){return ResumableConfiguration.Create(identifier: GetId(provider), filename: GetFileName(provider), chunks: GetTotalChunks(provider));}[NonAction]private string GetFileName(MultipartFormDataStreamProvider provider){var filename = provider.FormData["resumableFilename"];return !String.IsNullOrEmpty(filename) ? filename : provider.FileData[0].Headers.ContentDisposition.FileName.Trim(‘\"‘);}[NonAction]private string GetId(MultipartFormDataStreamProvider provider){var id = provider.FormData["resumableIdentifier"];return !String.IsNullOrEmpty(id) ? id : Guid.NewGuid().ToString();}[NonAction]private int GetTotalChunks(MultipartFormDataStreamProvider provider){var total = provider.FormData["resumableTotalChunks"];return !String.IsNullOrEmpty(total) ? Convert.ToInt32(total) : 1;}[NonAction]private int GetChunkNumber(MultipartFormDataStreamProvider provider){var chunk = provider.FormData["resumableChunkNumber"];return !String.IsNullOrEmpty(chunk) ? Convert.ToInt32(chunk) : 1;}#endregion#region Chunk methods[NonAction]private string GetChunkFileName(int chunkNumber, string identifier){return Path.Combine(root, string.Format("{0}_{1}", identifier, chunkNumber.ToString()));}[NonAction]private void RenameChunk(MultipartFileData chunk, int chunkNumber, string identifier){string generatedFileName = chunk.LocalFileName;string chunkFileName = GetChunkFileName(chunkNumber, identifier);if (File.Exists(chunkFileName)) File.Delete(chunkFileName);File.Move(generatedFileName, chunkFileName);}[NonAction]private string GetFilePath(ResumableConfiguration configuration){return Path.Combine(root, configuration.Identifier);}[NonAction]private bool ChunkIsHere(int chunkNumber, string identifier){string fileName = GetChunkFileName(chunkNumber, identifier);return File.Exists(fileName);}[NonAction]private bool AllChunksAreHere(ResumableConfiguration configuration){for (int chunkNumber = 1; chunkNumber <= configuration.Chunks; chunkNumber++)if (!ChunkIsHere(chunkNumber, configuration.Identifier)) return false;return true;}[NonAction]private void TryAssembleFile(ResumableConfiguration configuration){if (AllChunksAreHere(configuration)){// Create a single filevar path = ConsolidateFile(configuration);// Rename consolidated with original name of uploadRenameFile(path, Path.Combine(root, configuration.FileName));// Delete chunk filesDeleteChunks(configuration);}}[NonAction]private void DeleteChunks(ResumableConfiguration configuration){for (int chunkNumber = 1; chunkNumber <= configuration.Chunks; chunkNumber++){var chunkFileName = GetChunkFileName(chunkNumber, configuration.Identifier);File.Delete(chunkFileName);}}[NonAction]private string ConsolidateFile(ResumableConfiguration configuration){var path = GetFilePath(configuration);using (var destStream = File.Create(path, 15000)){for (int chunkNumber = 1; chunkNumber <= configuration.Chunks; chunkNumber++){var chunkFileName = GetChunkFileName(chunkNumber, configuration.Identifier);using (var sourceStream = File.OpenRead(chunkFileName)){sourceStream.CopyTo(destStream);}}destStream.Close();}return path;}#endregion[NonAction]private string RenameFile(string sourceName, string targetName){targetName = Path.GetFileName(targetName); // Strip to filename if directory is specified (avoid cross-directory attack)string realFileName = Path.Combine(root, targetName);if (File.Exists(realFileName)) File.Delete(realFileName);File.Move(sourceName, realFileName);return targetName;}}}

 github上給的demo裡邊的代碼~完全可以拿來用。然而並沒有webapp的代碼,我照著java的抄,發生了悲劇。不過稍微改改就好。

貼出來My Code

<div id="frame">    <link href="~/Content/resumablestyle.css" rel="stylesheet" />    <script src="~/Scripts/jquery-1.10.2.min.js"></script>    <script src="~/Scripts/resumable.js"></script>    <br />    <div class="resumable-drop" ondragenter="jQuery(this).addClass(‘resumable-dragover‘);" ondragend="jQuery(this).removeClass(‘resumable-dragover‘);" ondrop="jQuery(this).removeClass(‘resumable-dragover‘);">        將檔案拖拽到此處上傳 <a class="resumable-browse"><u>點擊選擇要上傳的檔案</u></a>    </div>    <div class="resumable-progress">        <table>            <tr>                <td width="100%"><div class="progress-container"><div class="progress-bar"></div></div></td>                <td class="progress-text" nowrap="nowrap"></td>                <td class="progress-pause" nowrap="nowrap">                    <a href="#" onclick="r.upload(); return(false);" class="progress-resume-link"><img src="~/Img/resume.png" title="Resume upload" /></a>                    <a href="#" onclick="r.pause(); return(false);" class="progress-pause-link"><img src="~/Img/pause.png" title="Pause upload" /></a>                </td>            </tr>        </table>    </div>    <ul class="resumable-list"></ul>    <script>        var r = new Resumable({            target: ‘@Url.Content("~/api/File/Upload")‘,            chunkSize: 1 * 1024 * 1024,            simultaneousUploads: 3,            //testChunks: false,            throttleProgressCallbacks: 1,            fileType: ["csv"]            //method: "octet"        });        // Resumable.js isn‘t supported, fall back on a different method        if (!r.support) {            $(‘.resumable-error‘).show();        } else {            // Show a place for dropping/selecting files            $(‘.resumable-drop‘).show();            r.assignDrop($(‘.resumable-drop‘)[0]);            r.assignBrowse($(‘.resumable-browse‘)[0]);            // Handle file add event            r.on(‘fileAdded‘, function (file) {                // Show progress pabr                $(‘.resumable-progress, .resumable-list‘).show();                // Show pause, hide resume                $(‘.resumable-progress .progress-resume-link‘).hide();                $(‘.resumable-progress .progress-pause-link‘).show();                // Add the file to the list                $(‘.resumable-list‘).append(‘<li class="resumable-file-‘ + file.uniqueIdentifier + ‘">Uploading <span class="resumable-file-name"></span> <span class="resumable-file-progress"></span>‘);                $(‘.resumable-file-‘ + file.uniqueIdentifier + ‘ .resumable-file-name‘).html(file.fileName);                // Actually start the upload                r.upload();            });            r.on(‘pause‘, function () {                // Show resume, hide pause                $(‘.resumable-progress .progress-resume-link‘).show();                $(‘.resumable-progress .progress-pause-link‘).hide();            });            r.on(‘complete‘, function () {                // Hide pause/resume when the upload has completed                $(‘.resumable-progress .progress-resume-link, .resumable-progress .progress-pause-link‘).hide();            });            r.on(‘fileSuccess‘, function (file, message) {                // Reflect that the file upload has completed                $(‘.resumable-file-‘ + file.uniqueIdentifier + ‘ .resumable-file-progress‘).html(‘(completed)‘);            });            r.on(‘fileError‘, function (file, message) {                // Reflect that the file upload has resulted in error                $(‘.resumable-file-‘ + file.uniqueIdentifier + ‘ .resumable-file-progress‘).html(‘(file could not be uploaded: ‘ + message + ‘)‘);            });            r.on(‘fileProgress‘, function (file) {                // Handle progress for both the file and the overall upload                $(‘.resumable-file-‘ + file.uniqueIdentifier + ‘ .resumable-file-progress‘).html(Math.floor(file.progress() * 100) + ‘%‘);                $(‘.progress-bar‘).css({ width: Math.floor(r.progress() * 100) + ‘%‘ });            });        }    </script></div>

  css樣式,表徵圖檔案,都是用的demo裡的。直接用就好。css中主要的就是:

/* Reset */#frame {margin:0 auto; width:800px; text-align:left;}/* Uploader: Drag & Drop *//*.resumable-error {display:none; font-size:14px; font-style:italic;}.resumable-drop {padding:15px; font-size:13px; text-align:center; color:#666; font-weight:bold;background-color:#eee; border:2px dashed #aaa; border-radius:10px; margin-top:40px; z-index:9999; display:none;}.resumable-dragover {padding:30px; color:#555; background-color:#ddd; border:1px solid #999;}*/.resumable-error {display:none; font-size:14px; font-style:italic;}.resumable-drop { padding:15px;font-size:13px; text-align:center; color:#666; font-weight:bold;background-color:#eee; border:2px dashed #aaa; border-radius:10px;  z-index:9999; display:none;}.resumable-dragover {padding:30px; color:#555; background-color:#ddd; border:1px solid #999;}/* Uploader: Progress bar */.resumable-progress {margin:30px 0 30px 0; width:100%; display:none;}.progress-container {height:7px; background:#9CBD94; position:relative; }.progress-bar {position:absolute; top:0; left:0; bottom:0; background:#45913A; width:0;}.progress-text {font-size:11px; line-height:9px; padding-left:10px;}.progress-pause {padding:0 0 0 7px;}.progress-resume-link {display:none;}.is-paused .progress-resume-link {display:inline;}.is-paused .progress-pause-link {display:none;}.is-complete .progress-pause {display:none;}/* Uploader: List of items being uploaded */.resumable-list {overflow:auto; margin-right:-20px; display:none;}.uploader-item {width:148px; height:90px; background-color:#666; position:relative; border:2px solid black; float:left; margin:0 6px 6px 0;}.uploader-item-thumbnail {width:100%; height:100%; position:absolute; top:0; left:0;}.uploader-item img.uploader-item-thumbnail {opacity:0;}.uploader-item-creating-thumbnail {padding:0 5px; font-size:9px; color:white;}.uploader-item-title {position:absolute; font-size:9px; line-height:11px; padding:3px 50px 3px 5px; bottom:0; left:0; right:0; color:white; background-color:rgba(0,0,0,0.6); min-height:27px;}.uploader-item-status {position:absolute; bottom:3px; right:3px;}/* Uploader: Hover & Active status */.uploader-item:hover, .is-active .uploader-item {border-color:#4a873c; cursor:pointer; }.uploader-item:hover .uploader-item-title, .is-active .uploader-item .uploader-item-title {background-color:rgba(74,135,60,0.8);}/* Uploader: Error status */.is-error .uploader-item:hover, .is-active.is-error .uploader-item {border-color:#900;}.is-error .uploader-item:hover .uploader-item-title, .is-active.is-error .uploader-item .uploader-item-title {background-color:rgba(153,0,0,0.6);}.is-error .uploader-item-creating-thumbnail {display:none;}

  基本就這麼多,簡單粗暴.....效果還是很好的,能實現大檔案分區上傳,多檔案上傳處理,內建進度條提示,省了好多事,說下參數含義:target:後台API,chunkSize:分區大小,fileType:檔案類型。

Html5 js上傳外掛程式resumable.js 的使用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.