如何从输入文件控件中删除一个特定的选定文件

Nav*_*eon 42 javascript jquery file-upload multifile

如何从输入文件控件中删除一个特定的选定文件?

我有一个输入文件控件,可以选择多个文件; 但是,我想验证一个文件,如果它有一个错误的扩展名,那么我应该从文件控件本身删除该文件,是否可能?

我尝试如下

<input type="file" name="fileToUpload" id="fileToUpload" multiple/>


<script> $("#fileToUpload")[0].files[0] </script>
Run Code Online (Sandbox Code Playgroud)

下面是对象的屏幕截图,但我无法修改它

在此输入图像描述

And*_*bbs 38

正如其他人所指出的那样,FileList只读.您可以通过将这些文件推送到单独的文件来解决这个问题Array.然后,您可以使用精选的文件列表执行任何操作.如果将目标上传到服务器,则可以使用FileReaderAPI.

下面是关于完全避免需要修改的方法FileList.脚步:

  1. 添加普通文件输入更改事件侦听器
  2. 从更改事件循环遍历每个文件,过滤所需的验证
  3. 将有效文件推入单独的数组
  4. 使用FileReaderAPI在本地读取文件
  5. 将有效的已处理文件提交给服务器

事件处理程序和基本文件循环代码:

var validatedFiles = [];
$("#fileToUpload").on("change", function (event) {
  var files = event.originalEvent.target.files;
  files.forEach(function (file) {
    if (file.name.matches(/something.txt/)) {
      validatedFiles.push(file); // Simplest case
    } else { 
      /* do something else */
    }
  });
});
Run Code Online (Sandbox Code Playgroud)

下面是一个更复杂的文件循环版本,它显示了如何使用FileReaderAPI将文件加载到浏览器中,并可选择将其作为Base64编码的blob提交给服务器.

  files.forEach(function (file) {
    if (file.name.matches(/something.txt/)) { // You could also do more complicated validation after processing the file client side
      var reader = new FileReader();
      // Setup listener
      reader.onload = (function (processedFile) {
        return function (e) {
          var fileData = { name : processedFile.name, fileData : e.target.result };

          // Submit individual file to server
          $.post("/your/url/here", fileData);

          // or add to list to submit as group later
          validatedFiles.push(fileData);
        };
      })(file);

      // Process file
      reader.readAsDataURL(file);
    } else { 
      /* still do something else */
    }
  });
Run Code Online (Sandbox Code Playgroud)

关于使用FileReaderAPI的注意事项.Base64编码文件将使其大小增加约30%.如果这是不可接受的,你将需要尝试别的东西.

  • 嗨,只有一件事.文件是一个javascript对象所以你不能在它上面使用.forEach,你应该这样做[] .forEach.call(files,function(file){....}) (2认同)

小智 7

我知道这是一篇旧帖子,但我花了很长时间尝试解决这个问题,所以我将发布我的解决方案。有一种方法可以用另一个 fileList 来更新 fileField 元素的 fileList - 这可以通过 DataTransfer 来完成:

let updateFileList = function (fileField, index) {
  let fileBuffer = Array.from(fileField.files);
  fileBuffer.splice(index, 1);

  /** Code from: /sf/answers/3302068661/ */
  const dT = new ClipboardEvent('').clipboardData || // Firefox < 62 workaround exploiting https://bugzilla.mozilla.org/show_bug.cgi?id=1422655
    new DataTransfer(); // specs compliant (as of March 2018 only Chrome)

  for (let file of fileBuffer) { dT.items.add(file); }
  fileField.files = dT.files;
}
Run Code Online (Sandbox Code Playgroud)

上面的函数将 fileField 作为 DOM 对象,以及要删除的 fileField 的 fileList 中的文件索引,并相应地更新传递的 fileField。

希望这可以节省其他人的时间!

如何在 FileList 对象中设置 File 对象和 length 属性,其中文件也反映在 FormData 对象中?


Mic*_*iti 5

我想我也应该在这里添加我的评论(我已经在这里回答:JavaScript delete File from FileList to be upload

我找到了一个解决方法。这根本不需要 AJAX 请求,表单可以发送到服务器。基本上,您可以创建一个hiddentext输入并将其value属性设置为处理所选文件后创建的base64 字符串。

<input type=hidden value=${base64string} />
Run Code Online (Sandbox Code Playgroud)

您可能会考虑创建多个输入文件而不是 inputtexthidden. 这将不起作用,因为我们无法为其分配值。

此方法将在发送到数据库的数据中包含输入文件并忽略输入文件,您可以:

  • 在后端不考虑领域;
  • 您可以disabled在序列化表单之前将属性设置为输入文件;
  • 在发送数据之前删除 DOM 元素。

当您想删除文件时,只需获取元素的索引并从 DOM 中删除输入元素(文本或隐藏)。

要求:

  • 您需要编写逻辑以在 base64 中转换文件并将所有文件存储在数组中,只要输入文件触发change事件。

优点:

  • 这基本上会给你很多控制,你可以过滤、比较文件、检查文件大小、MIME 类型等等。