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

IT技术 javascript jquery html firefox
2021-02-26 03:47:14

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

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

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

  1. 我检查拖动的项目是否没有类型和大小,如下所示,并且在大多数情况下它按预期工作。从我读过的内容来看,这不是有效的,也不是一直成功,因为有些文件可能没有文件扩展名,所以我尝试使用 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 ?
        }
    
    }}
    
  2. 在以下解决方案中,我尝试使用 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 中做到这一点?如果可能,我不想依赖第三方库或服务器端处理。任何建议 - 评论将不胜感激。

3个回答

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

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

例如,通过使用 Drang'n'Drop 事件: 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>

相关 Bugzilla:

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

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

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
2021-04-28 03:47:14
它已在 FF50(2016 年 11 月)中发布:bugzilla.mozilla.org/show_bug.cgi?id=876480#c21
2021-04-29 03:47:14
应该注意的是,输入对话框方法目前不适用于已发布的版本。
2021-05-09 03:47:14
这似乎已被删除。event.dataTransfer.getFilesAndDirectories不存在。
2021-05-19 03:47:14

这是我为解决此问题所做的工作:

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 字节,您可以很好地对文件夹进行切片,它将返回一个该大小的块。
2021-04-26 03:47:14
请注意,我的建议是从 2016 年开始的,大约是三年前。不能保证它会在 2019 年运行,因为浏览器技术一直在变化。
2021-04-26 03:47:14
非常聪明。感谢那!
2021-05-16 03:47:14

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

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

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

微软有这个关于该功能的非官方边缘文档,如果您对在 IE 中尝试这个功能也有疑问,这可能会很有趣。