【问题标题】:React: input type "file" ignores `accept` property when you upload files using drag and drop反应:当您使用拖放上传文件时,输入类型“文件”会忽略“接受”属性
【发布时间】:2022-01-19 10:21:09
【问题描述】:
我使用带有接受属性的<input type="file" accept=".txt" />。例如,我将其设置为仅接受 .txt 文件。如果您点击input并打开选择器并且您无法上传accept不允许的文件,则效果很好。
但是,当您通过drag & drop 上传文件时,它会上传忽略accept 的所有文件。
这是一个例子:
https://codesandbox.io/s/floral-tdd-11wt9?file=/src/App.js
重现问题:
- 从你的桌面拖动任何文件,期待
.txt
- 移动并放入输入中
- 您会看到一个文件名(但不应上传)
问:解决此问题的最佳方法是什么?考虑到可能有任何文件类型和标准file.type 提供有关文件类型的过多信息。
【问题讨论】:
标签:
javascript
reactjs
input
input-type-file
【解决方案1】:
当您添加接受时,浏览器会告诉操作系统仅显示提及但支持的文件,但是当您进行拖放时,此功能会被消除,
最好的方法是编写一个验证器函数来检查给定文件是否受支持
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
【解决方案2】:
为防止丢弃未接受的文件,您需要为输入添加 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();
}
};
这是一个活生生的例子: