file-upload html5上传 - HTML5是否允许拖放上传文件夹或文件夹树?




js拖动图片 js上传文件夹 (7)

Firefox现在支持文件夹上传,截至2016年11月15日,版本为v50.0: https://developer.mozilla.org/en-US/Firefox/Releases/50#Files_and_directorieshttps://developer.mozilla.org/en-US/Firefox/Releases/50#Files_and_directories

您可以将文件夹拖放到Firefox中,也可以浏览并选择要上载的本地文件夹。 它还支持嵌套在子文件夹中的文件夹。

这意味着您现在可以使用Chrome,Firefox,Edge或Opera上传文件夹。 您目前无法使用Safari或Internet Explorer。

我没有看到任何这样做的例子。 api规范中不允许这样做吗?

我正在寻找一个简单的拖放解决方案,用于上传整个文件夹树的照片。


现在可以了,感谢Chrome> = 21。

function traverseFileTree(item, path) {
  path = path || "";
  if (item.isFile) {
    // Get file
    item.file(function(file) {
      console.log("File:", path + file.name);
    });
  } else if (item.isDirectory) {
    // Get folder contents
    var dirReader = item.createReader();
    dirReader.readEntries(function(entries) {
      for (var i=0; i<entries.length; i++) {
        traverseFileTree(entries[i], path + item.name + "/");
      }
    });
  }
}

dropArea.addEventListener("drop", function(event) {
  event.preventDefault();

  var items = event.dataTransfer.items;
  for (var i=0; i<items.length; i++) {
    // webkitGetAsEntry is where the magic happens
    var item = items[i].webkitGetAsEntry();
    if (item) {
      traverseFileTree(item);
    }
  }
}, false);

更多信息: https://protonet.info/blog/html5-experiment-drag-drop-of-folders/https://protonet.info/blog/html5-experiment-drag-drop-of-folders/


HTML5规范并没有说明在选择要上传的文件夹时,浏览器应该递归上传所有包含的文件。

实际上,在Chrome / Chromium中,您可以上传文件夹,但是当您这样做时,它只会上传一个无意义的4KB文件,该文件代表该目录。 像Alfresco这样的服务器端应用程序可以检测到这一点,并警告用户无法上传文件夹:



此函数将为您提供所有已删除文件的数组的承诺,例如<input type="file"/>.files

function getFilesWebkitDataTransferItems(dataTransferItems) {
  function traverseFileTreePromise(item, path='') {
    return new Promise( resolve => {
      if (item.isFile) {
        item.file(file => {
          file.filepath = path + file.name //save full path
          files.push(file)
          resolve(file)
        })
      } else if (item.isDirectory) {
        let dirReader = item.createReader()
        dirReader.readEntries(entries => {
          let entriesPromises = []
          for (let entr of entries)
            entriesPromises.push(traverseFileTreePromise(entr, path + item.name + "/"))
          resolve(Promise.all(entriesPromises))
        })
      }
    })
  }

  let files = []
  return new Promise((resolve, reject) => {
    let entriesPromises = []
    for (let it of dataTransferItems)
      entriesPromises.push(traverseFileTreePromise(it.webkitGetAsEntry()))
    Promise.all(entriesPromises)
      .then(entries => {
        //console.log(entries)
        resolve(files)
      })
  })
}

用法:

dropArea.addEventListener("drop", function(event) {
  event.preventDefault();

  var items = event.dataTransfer.items;
  getFilesFromWebkitDataTransferItems(items)
    .then(files => {
      ...
    })
}, false);

现在您可以通过拖放和输入上传目录。

<input type='file' webkitdirectory >

和拖放(对于webkit浏览器)。

处理拖放文件夹。

<div id="dropzone"></div>
<script>
var dropzone = document.getElementById('dropzone');
dropzone.ondrop = function(e) {
  var length = e.dataTransfer.items.length;
  for (var i = 0; i < length; i++) {
    var entry = e.dataTransfer.items[i].webkitGetAsEntry();
    if (entry.isFile) {
      ... // do whatever you want
    } else if (entry.isDirectory) {
      ... // do whatever you want
    }
  }
};
</script>

资源:

http://updates.html5rocks.com/2012/07/Drag-and-drop-a-folder-onto-Chrome-now-available


对于我们自己的应用程序,我们只对FireFox进行拖放。 我们恢复到其他人的传统iframe上传。 为了检测是否支持拖放操作,我们运行以下代码:

if (typeof(window.File) == 'object' && typeof(window.FileReader) == 'function' && typeof(window.FileList) == 'object') {
   // DnD is supported!
}

希望这对一些人有帮助。





html5 file-upload drag-and-drop