百度Webuploader 大文件分片上傳(.net接收)
前陣子要做個大文件上傳的功能,找來找去發現Webuploader還不錯,關於她的介紹我就不再贅述。
動手前,在園子里找到了一篇不錯的分片上傳的帖子,參考之后,踏出了第一步。此文記錄我這次實踐的點滴,僅作分享與討論。
關於插件的使用可以參考快速使用文檔。在Github上下載了最新的壓縮包后,基於其中的一個例子(image-upload)做了修改,主要是補充了.net后台分片接收文件的實現。
先上干貨:WebUploadTest.zip 提取碼:fikn
分片上傳的上傳邏輯已經有控件實現。保存分片的邏輯是:
每次上傳文件,用js生成一個guid。請看upload.js 87行
GUID = WebUploader.Base.guid()
webuploader配置參數時會用到上面的guid。上傳並發數自己改吧,>1經過測試貌似也可以(我一開始用其他代碼測試時>1有報錯過,如有出錯留作討論)
后台根據前端的guid,生成一個臨時文件夾,文件夾的用guid的值命名。然后分片文件以當前分片序數命名,保存在臨時文件夾。fileupload.ashx 24行
//取得chunk和chunks
int chunk = Convert.ToInt32(context.Request.Form["chunk"]);//當前分片在上傳分片中的順序(從0開始)
int chunks = Convert.ToInt32(context.Request.Form["chunks"]);//總分片數
//根據GUID創建用該GUID命名的臨時文件夾
string folder = context.Server.MapPath("~/1/" + context.Request["guid"]+"/");
string path = folder + chunk;//每個分片用數字命名
后台每次返回一個json字符串。關於這個返回值是可以像構造ajax返回參數一樣自定義的。我是這樣返回與接收的。請看fileupload.ashx 57行起
//...
context.Response.Write("{\"chunked\" : true, \"hasError\" : false, \"f_ext\" : \"" + Path.GetExtension(file.FileName) + "\"}"); } else//沒有分片直接保存 { context.Request.Files[0].SaveAs(context.Server.MapPath("~/1/" + DateTime.Now.ToFileTime() + Path.GetExtension(context.Request.Files[0].FileName))); context.Response.Write("{\"chunked\" : false, \"hasError\" : false}"); }
//...
接收的js如下:upload.js 544行
// 文件上傳成功,合並文件。 uploader.on('uploadSuccess', function (file, response) { if (response.chunked) { $.post("MergeFiles.ashx", { guid: GUID, fileExt: response.f_ext }, function (data) { data = $.parseJSON(data); if (data.hasError) { alert('文件合並失敗!'); } else { alert(decodeURIComponent(data.savePath)); } }); } });
由於上傳時,文件分片保存於以guid的值命名的文件夾中,所有,在單個文件全部上傳完畢之后,再發送一個異步請求到 MergeFiles.ashx 合並文件,合並是將臨時文件夾里的文件按文件名順序合並(文件名是數字)。
運行本代碼,在瀏覽器控制台可以觀察插件上傳文件的各個事件。
webuploader支持斷點續傳,但是由於官網例子的原因,我這個例子上的斷點是不能停止的,這里容我把樂趣留給大家。webuploader官網api有答案,改起來挺簡單的。呵呵