React:当您使用拖放上传文件时,输入类型 "file" 会忽略“接受”属性

React: input type "file" ignores `accept` property when you upload files using drag and drop

我使用 <input type="file" accept=".txt" /> 接受 属性。例如,我将其设置为仅接受 .txt 个文件。如果您单击 input 并打开选择器并且您无法上传 accept.

不允许的文件,则效果很好

但是,当您通过 drag & drop 上传文件时,它会忽略 accept 上传任何文件。

这是一个例子: https://codesandbox.io/s/floral-tdd-11wt9?file=/src/App.js

重现问题:

问:解决此问题的最佳方法是什么?考虑到可能存在任何文件类型和标准 file.type 会提供有关文件类型的过多信息。

当您添加接受时,浏览器会告诉 OS 仅显示提到但不支持的文件,但是当您进行拖放时,此功能将被消除, 最好的方法是编写一个验证器函数来检查给定的文件是否受支持,例如

 const handleChange = (e) => {
const newFiles = e.target.files;
const fileName = newFiles[0].name;
const extension = fileName.split(".").pop();
const isSupported = ["txt"].includes(extension);
if (!isSupported) {
  alert("not supported");
  setFiles(null);
  e.target.value = null;
} else {
  setFiles(newFiles);
}

};

这里使用["txt"].includes(extension)的好处是,你可以为多种文件类型添加验证,我只是用 e.target.value = null;(当文件无效时)重置输入,但你可以使用你在那里拥有逻辑

这是一个有效的 example

为了防止丢弃不接受的文件,您需要为输入添加 onDrop 处理程序:

<input type="file" onDrop={handleDrop} accept="text/plain" {...otherProps} />

onDrop 中检查是否接受丢弃的文件类型:

const handleDrop = (e) => {
  const allowedTypes = new Set([e.target.accept]);
  if (!allowedTypes.has(e.dataTransfer.files[0].type)) {
    // stop event prepagation
    e.preventDefault();
  }
};

这是一个活生生的例子: