文件夾上傳:從前端到後端前端
文件上傳是 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怎麼上傳文件夾/