1. 程式人生 > >js資料夾上傳

js資料夾上傳

資料夾上傳:從前端到後端

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

先說兩個問題:

  1. 是否所有後端框架都支援資料夾上傳?
  2. 是否所有瀏覽器都支援資料夾上傳?

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

只要後端框架對於表單的支援是完整的,那麼必然支援資料夾上傳。至於瀏覽器,截至目前,只有 Chrome 支援。 Chrome 大法好!

不要期望檔案上傳這個功能的瀏覽器相容性,這是做不到的。

好,假定我們的所有使用者都用上了 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

 也是必要的,解釋參見這裡

如果用 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 上傳的好處有兩點,首先是非同步,這樣不會導致頁面卡住,其次是能比較方便地實現上傳進度條。關於上傳進度條的實現可以參考這裡。需要注意的是contentTypeprocessData必須設定成false,參考了這裡