HTML5是否允许拖放上传文件夹或文件夹树?
我还没有看到任何这样做的例子。 这是不允许的API规范?
我正在寻找一个简单的拖放解决scheme来上传整个文件夹的照片树。
现在可以,感谢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/
在这封给HTML 5邮件列表的邮件里,Ian Hickson说:
HTML5现在必须一次上传多个文件。 浏览器可以允许用户一次select多个文件,包括跨多个目录; 这有点超出了规范的范围。
(另请参阅原始functionbuild议 。)因此,假设他认为使用拖放function上传文件夹也超出范围是安全的。 显然这是由浏览器服务于个人文件。
上传文件夹也会遇到一些其他的困难,如Lars Gunther所述 :
这个提案必须有两个支票(如果可以的话):
最大尺寸,阻止某人上传数百个未压缩原始图像的完整目录…
即使省略了accept属性也要过滤。 Mac OS元数据和Windows缩略图等应该省略。 所有隐藏的文件和目录应该默认排除。
现在你可以通过拖放和input来上传目录。
<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现在支持文件夹上传,截至2016年11月15日,v50.0: https : //developer.mozilla.org/en-US/Firefox/Releases/50#Files_and_directories
您可以将文件夹拖放到Firefox中,也可以浏览并select要上传的本地文件夹。 它也支持嵌套在子文件夹中的文件夹。
这意味着您现在可以使用Chrome,Firefox,Edge或Opera来上传文件夹。 目前您无法使用Safari或Internet Explorer。
这个函数会给你所有丢弃文件数组的承诺,比如<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);
HTML5规范并没有说在select上传文件夹时,浏览器应该recursion地上传所有包含的文件。
实际上,在Chrome / Chromium中,你可以上传一个文件夹,但是当你这样做的时候,它只是上传一个无意义的4KB文件,代表目录。 一些像Alfresco这样的服务器端应用程序可以检测到这一点,并警告用户不能上传文件夹:
HTML5是否允许拖放上传文件夹或文件夹树?
只有Chrome支持此function。 它没有任何牵引力,可能会被删除。
参考: https : //developer.mozilla.org/en/docs/Web/API/DirectoryReader#readEntries