Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何从输入文件控件中删除一个特定的选定文件_Javascript_Jquery_File Upload_Multifile - Fatal编程技术网

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

Javascript 如何从输入文件控件中删除一个特定的选定文件,javascript,jquery,file-upload,multifile,Javascript,Jquery,File Upload,Multifile,如何从输入文件控件中删除一个特定的选定文件 我有一个输入文件控件,可以选择多个文件;但是,我想验证一个文件,如果它有一个错误的扩展名,那么我应该从文件控件本身删除该文件,这可能吗 我试了如下 <input type="file" name="fileToUpload" id="fileToUpload" multiple/> <script> $("#fileToUpload")[0].files[0] </script> 下面是该对象的屏幕截图,但我无

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

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

我试了如下

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


<script> $("#fileToUpload")[0].files[0] </script>
下面是该对象的屏幕截图,但我无法修改它


正如其他人指出的,它是只读的。不过,您可以通过将这些文件放入一个单独的数组来解决这个问题。然后,你可以用这个精心策划的文件列表做任何你想做的事情。如果目标是将它们上载到服务器,则可以使用API

下面是一种完全避免修改文件列表的方法。 步骤:

添加普通文件输入更改事件侦听器 循环通过更改事件中的每个文件,筛选所需的验证 将有效文件推送到单独的数组中 使用FileReader API在本地读取文件 将已处理的有效文件提交到服务器 事件处理程序和基本文件循环代码:

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 */
    }
  });
});
下面是一个更复杂的文件循环版本,它显示了如何使用FileReader API将文件加载到浏览器中,并可以选择将其作为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 */
    }
  });
关于使用FileReader API的注意事项。Base64编码文件将使其大小增加约30%。如果这是不可接受的,您需要尝试其他方法。

html

<input id="fileInput" name="fileInput" type="file" />
<input onclick="clearFileInput()" type="button" value="Clear" />

我想我也应该在这里加上我的评论,我在这里回答:

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

<input type=hidden value=${base64string} />

您可能会考虑创建多个输入文件,而不是输入文本或隐藏。这将不起作用,因为我们无法为其赋值

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

在后端不要考虑领域; 在序列化表单之前,可以将禁用属性设置为输入文件; 在发送数据之前删除DOM元素。 当您想要删除一个文件时,只需获取元素的索引,并从DOM中删除输入元素文本或隐藏内容

要求:

您需要编写逻辑来转换base64中的文件,并在输入文件触发更改事件时将所有文件存储在一个数组中。 优点:

这基本上会给你很多控制,你可以过滤,比较文件,检查文件大小,MIME类型,等等。。
我知道这是一个老帖子,但我已经花了很多时间试图解决这个问题,所以我将发布我的解决方案。有一种方法可以使用另一个文件列表更新fileField元素的文件列表-这可以通过数据传输完成:

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

  /** Code from: https://stackoverflow.com/a/47172409/8145428 */
  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;
}
上面的函数将fileField作为DOM对象,并在fileField的fileList中删除文件的索引,并相应地更新传递的fileField

希望这能为其他人节省一些时间


你打算怎么处理这些文件?一旦用户上传它们,它们就被复制到你的tmp文件夹中,并且它们的信息保存在你的数组中,因此当你处理它们时,只需跳过任何扩展名错误的文件…伙计们,它不是数组,它是一个具有属性0,1,2的对象,因此我无法在此执行数组操作不幸的是,你无法修改文件列表中的文件,因为它们是只读的。创建新的文件列表似乎也是不可能的。使用输入元素的“accepts”属性是否有可能解决您的问题?您可以使用以下命令从文件列表中删除所有文件:$fileToUpload[0]。value=Related post:Hi,只需一件事。文件是一个javascript对象,因此您不能在其上使用。forEach,您应该改为使用[]。forEach.callfiles,functionfile{…}此解决方案仅在您不从表单Submit上载文件而不是将单个文件提交到服务器时有效,我如何才能让它发布整个数组?@AndrewHubbs如何再次使用多个文件输入附加已验证的文件?从输入元素的何处删除文件?如果一个用户上传了5个文件,而你所做的只是操纵一个JavaScript数组,他们仍然会在输入按钮旁边看到“选择了5个文件”。这是个不错的主意。。。我将用newInput替换用于实际表单提交的实际hiddenInput,并将oldInput保持原样。这是一个很好的解决方案,但不幸的是,它在iOS上不起作用
let updateFileList = function (fileField, index) {
  let fileBuffer = Array.from(fileField.files);
  fileBuffer.splice(index, 1);

  /** Code from: https://stackoverflow.com/a/47172409/8145428 */
  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;
}