无法在表单中预览多个上传文件

Can not preview multiple uploading files in form

在多部分表单中,我可以使用以下方法预览单个上传图片:

 function readURL(input) {
      if (input.files && input.files[0]) {
        var reader = new FileReader();
        reader.onload = function (e) {
          let image = new Image();
          image.src = `${e.target.result}`;
          image.className = "img-thumbnail"
          let closeBtn = `<button type="button" class="close"></button>`;
          let wrapper = $('<div class="image-wrapper" />');
          $('#images-to-upload').append(wrapper);
          $(wrapper).append(image);
          $(wrapper).append(closeBtn);
        }
    
        reader.readAsDataURL(input.files[0]); 
      }
    }
    
    $("#imgInput").change(function () {
      readURL(this);
    });

但我想预览所有上传的图片,所以我通过添加一个 for 循环对上面的代码进行了此调整:

function readURL(input) {
  if (input.files && input.files[0]) {
    let files = input.files;
    
    for (var i = 0; i < input.files.length; i++) {
      var reader = new FileReader();
      reader.onload = function (e) {
        let image = new Image();
        image.src = `${e.target.result[i]}`;
        image.className = "img-thumbnail"
        let closeBtn = `<button type="button" class="close"></button>`;
        let wrapper = $('<div class="image-wrapper" />');
        $('#images-to-upload').append(wrapper);
        $(wrapper).append(image);
        $(wrapper).append(closeBtn);
  
      }
      };

    reader.readAsDataURL(input.files[i]); // error here
  }
}

但现在我得到这个错误:

143 Uncaught TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'

我该如何解决这个问题?

因为reader.readAsDataURL(input.files[i]);在循环外。但这不是你这样做的方式。 FileReader 一次只能处理一个文件。这意味着您必须为输入中的每个图像创建 FileReader 的实例。

为了便于阅读,我建议将其拆分为 2 个函数。


function previewImage(file) {
  const reader = new FileReader();
  reader.onload = function (e) {
    let image = new Image();
    image.src = e.target.result;
    image.className = "img-thumbnail";
    let closeBtn = `<button type="button" class="close"></button>`;
    let wrapper = $('<div class="image-wrapper" />');
    $("#images-to-upload").append(wrapper);
    $(wrapper).append(image);
    $(wrapper).append(closeBtn);
  };
  reader.readAsDataURL(file);
}

function readURL(input) {
  if (input.files.length) {
    Array.from(input.files).forEach((file) => previewImage(file));
  }
}

我做了一些修改:

  • if (input.files.length) { - 文件输入总是有文件 FileList 对象,因此无需检查它是否存在,您只需检查它是否有长度,这意味着至少存在一个文件
  • Array.from(input.files) - 将 FileList 转换为常规数组,您可以使用数组函数,例如 forEach

其他的都差不多。在 image.src = e.target.result; 中,不需要将其设为字符串,因为它已经是一个字符串。 FileReader class 上的结果集也不能是数组。