Firefox 中的 HTML5 拖放文件夹检测。甚至可能吗?

Posted

技术标签:

【中文标题】Firefox 中的 HTML5 拖放文件夹检测。甚至可能吗?【英文标题】:HTML5 drag and drop folder detection in firefox. Is it even possible? 【发布时间】:2014-06-18 20:15:39 【问题描述】:

我有一个放置区,我想检测拖动的项目是文件夹还是文件。在 chrome 中,我通过使用实现了这一点

for (var i = 0; i < nrOfFiles; i++) 
    var entry = e.originalEvent.dataTransfer.items[i].webkitGetAsEntry();
    if (entry.isDirectory) 
        //folder detection

在 Firefox 中无法使用上述解决方案(webkit),在花了很多时间试图解决这个问题后,我想出了以下解决方案(但失败了)

    我检查拖动的项目是否没有如下所示的类型和大小,并且在大多数情况下它按预期工作。从我读过的内容来看,这不是有效的,并且总是不成功,因为某些文件可能没有文件扩展名,所以我尝试使用 FileReader API 将文件读取为二进制字符串(readAsBinaryString)或 readAsArrayBuffer 并捕获异常以防项目是不可读,但永远不会抛出异常。

    var files = e.originalEvent.dataTransfer.files;
    for (var i = 0; i < nrOfFiles; i++) 
    if (files[i].size === 0 && files[i].type==="") 
    
        try
           var reader = new FileReader();
            reader.readAsBinaryString(files[i]);
        catch(e)
            //folder detection ?
        
    
    
    

    在以下解决方案中,我尝试使用 mozGetDataAt,它是相应的 webkitGetAsEntry(??? 不是 100%,如果我错了请纠正我),但我遇到了安全异常。

    var entry = e.originalEvent.dataTransfer.mozGetDataAt("application/x-moz-file",i);
    if (entry.isDirectory)  //not even reaching this statement. idk if isDirectory is applicable to entry
        //folder detection?
    
    

例外是:

http://localhost:8080 为 UnnamedClass 类的对象创建包装器的权限被拒绝

在 Firefox 中真的有办法做到这一点吗?如果可能的话,我不想依赖第三方库或服务器端处理。任何建议-cmets 将不胜感激。

【问题讨论】:

现在可以了!看我的回答:***.com/a/33431704/195216 【参考方案1】:

在 Firefox 42 及更高版本中是可能的(https://developer.mozilla.org/en-US/Firefox/Releases/42,https://nightly.mozilla.org/):

https://jsfiddle.net/28g51fa8/3/

使用拖放事件:e.dataTransfer.getFilesAndDirectories();

或者,使用新的输入对话框,让用户在文件或文件夹上传之间进行选择:

<input id="dirinput" multiple="" directory="" type="file" />
<script>
var dirinput = document.getElementById("dirinput");
dirinput.addEventListener("change", function (e) 
  if ('getFilesAndDirectories' in this) 
    this.getFilesAndDirectories().then(function(filesAndDirs) 
        for (var i=0, arrSize=filesAndDirs.length; i < arrSize; i++) 
            iterateFilesAndDirs(filesAndDirs[i]);
        
    );
  
, false);
</script>

相关的 Bugzillas:

https://bugzilla.mozilla.org/show_bug.cgi?id=1164310(实施 MS 关于减少新 FileSystem API 子集的提议)

https://bugzilla.mozilla.org/show_bug.cgi?id=1188880(发送目录拣选和目录拖放)

https://bugzilla.mozilla.org/show_bug.cgi?id=1209924(支持过滤Directory::GetFilesAndDirectories)

https://bugzilla.mozilla.org/show_bug.cgi?id=876480#c21(在 Firefox 50 中发布,2016 年 11 月)

部分代码来自: https://jwatt.org/blog/2015/09/14/directory-picking-and-drag-and-drop (https://archive.is/ZBEdF)

很遗憾,目前还没有在 MS Edge 中: https://dev.modern.ie/platform/status/draganddropdirectories/

【讨论】:

对于 Firefox,最终必须在“about:config”中创建一个新的布尔属性:dom.input.dirpicker=true 需要注意的是,输入对话框方法目前在已发布的版本中不起作用。 已在FF50(2016年11月)发布:bugzilla.mozilla.org/show_bug.cgi?id=876480#c21 这似乎已被删除。 event.dataTransfer.getFilesAndDirectories 不存在。【参考方案2】:

这是我为解决这个问题所做的:

var files = [];

for( var i = 0; i < e.dataTransfer.files.length; i++ )
    var ent = e.dataTransfer.files[i];
    if( ent.type ) 
        // has a mimetype, definitely a file
        files.push( ent );
     else 
        // no mimetype:  might be an unknown file or a directory, check
        try 
            // attempt to access the first few bytes of the file, will throw an exception if a directory
            new FileReader().readAsBinaryString( ent.slice( 0, 5 ) ); 
            // no exception, a file
            files.push( ent );
         catch( e ) 
            // could not access contents, is a directory, skip
        
    

基本上:

如果拖放条目具有 mime 类型,则它是一个文件 否则,请尝试读取条目内容 只读取前5个字节(避免意外将大文件加载到内存中):ent.slice( 0, 5 ) 如果读取成功,则为文件 如果读取失败,那么这是一个目录

享受吧!

【讨论】:

非常聪明。谢谢! 这并不是在所有情况下都抛出异常。在 *nix 系统上,文件夹是 4096 字节,你可以对文件夹进行切片,它会返回那个大小的块。 请注意我的建议是从 2016 年开始的,大约三年前。无法保证它会在 2019 年使用,因为浏览器技术一直在变化。【参考方案3】:

您的问题的简单答案是“否”,无法在 Firefox 中使用拖放来读取文件夹。

似乎还没有处理文件夹的 html5 标准。 Chrome 处理文件夹的能力是他们在浏览器中内置的自定义(标准之外)。

目前无法使用 HTML5/javascript 在 Firefox(或我相信的 IE)中进行文件夹拖放。 Mozilla's bugzilla 上的此功能有一个“错误”,它提到 W3C 目前已停止为涵盖目录的文件系统 API 创建标准规范(尽管有此 editor's draft)。该 Mozilla 错误仍处于 NEW 状态,并未显示为已分配/已占用。

Microsoft 提供了 this unofficial edge document 的功能,如果您对在 IE 中尝试此功能也有疑问,这可能会很有趣。

【讨论】:

以上是关于Firefox 中的 HTML5 拖放文件夹检测。甚至可能吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用 HTML5 拖放防止拖动事件干扰 Firefox 中的输入元素

HTML5 拖放 - Firefox 被重定向

为啥 HTML5 拖放功能在 Firefox 中不起作用?

在 javascript 中检测 HTML5 拖放支持

Firefox html5拖放不起作用

HTML5 拖放 getData() 仅适用于 Chrome 中的拖放事件?