组合一个'Drop Zone'带有'常规文件输入'

Combining a 'Drop-Zone' with a 'regular file-input'

本文关键字:常规 文件 输入 带有 Zone 合一 组合 Drop      更新时间:2023-09-26

这是我担心以前已经回答过的问题,但我什么都找不到。

我正在开发一个普通的web应用程序。它的一部分是一个文件上传器,它将xml文件上传到Java servlet,然后对其进行解析并导入数据库。

直到最近,启用此功能的html和javascript看起来如下(请注意,讽刺和/或无益的注释被放在了与问题无关的大块代码中(:

html

<form id="import_form">
  <!-- Some irrelevant divs here --> 
  <span class="btn btn-default btn-file">
        Browse <input name="filesToUpload[]" id="filesToUpload" type="file" multiple="" accept="" onchange="updateFileList();"/>
  </span>
  <!-- Some irrelevant divs here --> 
</form>

Javascript

function submitImport() {
    var formData = new FormData($('#import_form')[0]);
    $.ajax({
        url : "uploadEndpoint",
        type : "POST",
        data : formData,
        /* Some more elements */
        success : function(response) {
            // Handle success, it ain't easy
        },
        error : function(request, error, status){
            // Handle failure, weep
        }
    });

当用户通过一组按钮点击自己时,就会调用submitImport方法。

这一切都很好,效果也很好。然而,为了让web应用程序更酷,今天,我尝试添加一个"投递区":

html

<div id="drop-zone">
    <p class="info">Or drop files here</p>
</div>

Javascript

// Handler for the drop-zone
$('#drop-zone').on('dragover', function(event){
    event.preventDefault();
    event.stopPropagation();
    if(!event.dataTransfer){
        event.dataTransfer = event.originalEvent.dataTransfer;
    }
    event.dataTransfer.dropEffect = "copy";
    $(this).css("background-color", "#f5f5f5");
}).on('dragleave', function(event){
    event.preventDefault();
    event.stopPropagation();
    $(this).css("background-color", "#fff");
}).on('drop', function(event){
    event.preventDefault();
    event.stopPropagation();
    if(!event.dataTransfer){
        event.dataTransfer = event.originalEvent.dataTransfer;
    }    
    var files = event.dataTransfer.files;
    // Okey so what now?
});

还和我在一起吗?好的,所以我的问题是:

如何在一个区块中通过$.ajax发送从"浏览"输入、放置区域添加的文件?

正如Okey so what now?评论所指出的,我真的不知道该如何处理添加到放置区中的文件。我可以很容易地用获取"浏览"输入的表单文件

$("#filesToUpload").prop("files");

然而,我已经明白FileList是不可变的,所以这对我没有太大帮助,因为我不能将第一个附加到第二个。

由于特定于应用程序的原因,一个区块部分至关重要。因此,像顺序发送所有文件列表这样的解决方案并不理想。

请注意,我在任何与网络相关的事情上都是新手,所以如果答案摆在我面前,我很抱歉。

 var files = event.dataTransfer.files;
// Okey so what now?

好的,现在是以下内容:

是的,FileList对象是不可变的。但你不需要修改它们。只需将从FileList中删除的文件逐个添加到一个名为"files"的数组中。

然后,就在调用jQuery.ajax之前,您可以将files数组中的所有文件作为常规字段添加到FormData对象中。

例如:

步骤1-记住删除的文件

var files=event.dataTransfer.files

var files = [];
// (be sure to declare 'files' in a scope available in both of ondrop and form-submit methods)

onDrop:

for(var i = 0;i < event.dataTransfer.files.length;i++) {
    files.push(event.dataTransfer.files.item(i));
    // here you can add some DOM manipulations to show users what files have been dropped here
}

步骤2-将文件添加到FormData对象

for(var i = 0;i < fileList.length;i++) {
    formData.append('droppedFile[]', fileList[i]);
}

Voilà

问题是,您无法在随后的文件删除中检查重复项,因为出于安全原因,无法访问文件的完整本地路径(它在某些浏览器上可用,但我们不必依赖这种不可靠的功能(。