js實現大文件分片上傳的方法

文件夾上傳:從前端到後端前端

文件上傳是 Web 開發確定會碰到的問題,而文件夾上傳則更加難纏。網上關於文件夾上傳的資料多集中在前端,缺乏對於後端的關注,而後講某個後端框架文件上傳的文章又不會涉及文件夾。今天研究了一下這個問題,在此記錄。web

先說兩個問題:ajax

是否全部後端框架都支持文件夾上傳?算法

是否全部瀏覽器都支持文件夾上傳?數據庫

第一個問題:YES,第二個問題:NO後端

只要後端框架對於表單的支持是完整的,那麼必然支持文件夾上傳。至於瀏覽器,截至目前,只有 Chrome 支持。跨域

若是須要其它的瀏覽器支持則須要藉助於插件,好比澤優大文件上傳控件:www.webuploader.net瀏覽器

關於WebUploader的功能說明:安全

大文件上傳續傳服務器

支持超大文件上傳(100G+)和續傳,能夠關閉瀏覽器,重啓系統後仍然繼續上傳。

開源

提供ASP.NET,JSP,PHP示例和源代碼,其中JSP提供MySQL,Oracle,SQL Server數據庫的配置和示例代碼。

分片、併發

分片與併發結合,將一個大文件分割成多塊,併發上傳,極大地提升大文件的上傳速度。

當網絡問題致使傳輸錯誤時,只須要重傳出錯分片,而不是整個文件。另外分片傳輸可以更加實時的跟蹤上傳進度。

預覽、壓縮

支持經常使用圖片格式jpg,jpeg,gif,bmp,png預覽與壓縮,節省網絡數據傳輸。

解析jpeg中的meta信息,對於各類orientation作了正確的處理,同時壓縮後上傳保留圖片的全部原始meta數據。

多途徑添加文件

支持文件多選,類型過濾,拖拽(文件&文件夾),圖片粘貼功能。上傳本地指定路徑的文件,不須要經過點擊按鈕選擇文件。

粘貼功能主要體如今當有圖片數據在剪切板中時(截屏工具如QQ(Ctrl + ALT + A), 網頁中右擊圖片點擊複製),Ctrl + V即可添加此圖片文件。

HTML5 & FLASH

兼容主流瀏覽器和低版本瀏覽器,接口一致,實現了兩套運行時支持,用戶無需關心內部用了什麼內核。並且支持IE6,IE8瀏覽器。

同時Flash部分沒有作任何UI相關的工做,方便不關心flash的用戶擴展和自定義業務需求。

基於內存映射模式進行IO操做,充分發揮操做系統性能。

MD5秒傳

當文件體積大、量比較多時,支持上傳前作文件md5值驗證,一致則可直接跳過。

若是服務端與前端統一修改算法,取段md5,可大大提高驗證性能,耗時在20ms左右。

易擴展、可拆分

採用可拆分機制, 將各個功能獨立成了小組件,可自由搭配。

採用AMD規範組織代碼,清晰明瞭,方便高級玩家擴展。

文件夾上傳

支持10萬+級別的文件夾上傳,續傳。

支持層級目錄結構保存,上傳後可以將數據庫層級信息保存在數據庫中。

提供MySQL,Oracle,SQL Server數據庫支持。

支持文件夾續傳,在瀏覽器刷新,重啓後仍然可以繼續上傳。

支持跨域上傳。

PC端全平臺支持

支持Windows,macOS,Linux。支持國產化操做系統,支持政務信息安全項目。

其中Windows支持低版本系統:Windows XP。

其中瀏覽器包括:IE6,IE7,IE8(x86,x64),IE9(x86,x64),IE10(x86,x64),IE11(x86,x64),360安全瀏覽器,360極速瀏覽器,QQ瀏覽器,搜狗瀏覽器,Maxthon(遨遊)瀏覽器1.X,Maxthon(傲遊)瀏覽器2.x,Firefox,Chrome,Opera 23+

選擇文件夾進行上傳

 

 

文件夾上傳完畢

 

 

文件夾上傳後在服務器中的層級結構

 

 

 

好,假定咱們的全部用戶都用上了 Chrome,要怎麼作才能成功上傳一個文件夾呢?這裏不用drop這種高大上的東西,就用最傳統的<input>。用表單 submit 和 ajax 均可以作,先看 submit 方式。

<form method="POST" enctype=multipart/form-data>

  <input type='file' name="file" webkitdirectory >

  <button>upload</button>

</form>

咱們只要添加上 webkitdirectory 這個屬性,在選擇的時候就能夠選擇一個文件夾了,若是不加,文件夾被選中的時候就是灰色的。不過貌似加上這個屬性就無法選中文件了... enctype=multipart/form-data 也是必要的,解釋參見這裏:http://blog.ncmem.com/wordpress/2019/08/09/js怎麼上傳文件夾/

 

若是用 ajax 方式,咱們能夠省去<form>,只留下<input>就 OK。

<input type='file' webkitdirectory > 

<button id="upload-btn" type="button">upload</button> 

可是這樣是不夠的,關鍵在於 Js 的使用。

var files = [];

$(document).ready(function(){

  $("input").change(function(){

    files = this.files;

  });

});

$("#upload-btn").click(function(){

  var fd = new FormData();

  for (var i = 0; i < files.length; i++) {

    fd.append("file", files[i]);

  }

  $.ajax({

    url: "/upload/",

    method: "POST",

    data: fd,

    contentType: false,

    processData: false,

    cache: false,

    success: function(data){

      console.log(data);

    }

  });

});

用 ajax 方式,咱們必須手動構造一個 FormData Object, 而後放在 data 裏面提交到後端。 FormData 好像就只有一個 append 方法,第一個參數是 key,第二個參數是 value,用來構造表單數據。ajax請求中,經過 input 元素的 files 屬性獲取上傳的文件。files屬性不論加不加 webkitdirectory 都是存在的,用法也基本同樣。不過當咱們上傳文件夾時,files 中會包含文件相對路徑的信息,以後會看到。

用 ajax 上傳的好處有兩點,首先是異步,這樣不會致使頁面卡住,其次是能比較方便地實現上傳進度條。關於上傳進度條的實現能夠參考這裏。須要注意的是contentType和processData必須設置成false,參考了這裏:http://blog.ncmem.com/wordpress/2019/08/09/js怎麼上傳文件夾/

相關文章
相關標籤/搜索