<input type="file">的accept属性在拖放文件时将被忽略,我该如何防止这种情况发生?

3

我希望限制用户只能选择CSV或Excel文件。

请参考以下最简示例:

<input type="file" accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel">

尽管我可以使用accept属性来强制文件选择器不选择其他文件,但我仍然可以直接从Finder中拖放文件,并且它可以正常工作--accept属性将被忽略。
有没有可能防止这种情况发生?

2
很确定你需要手动进行JavaScript/服务器端检查。 - Uuuuuumm
3个回答

3

您需要进行服务器端验证,但是可以通过将文件类型与允许类型的Set进行比较来改善用户体验。

const allowedTypes = new Set(['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 
   'application/vnd.ms-excel']);
document.querySelector('input[type=file]').addEventListener('change', function(){
  if(!allowedTypes.has(this.files[0].type)){
    console.log("Not a CSV file");
    this.value = '';//clear the input for invalid file
  } else {
    console.log("CSV file");
  }
});
<input type="file" accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel">


1
请注意,csv文件有许多MimeTypes,因此您应该检查更多的类型,而不仅仅是"application/vnd.ms-excel" => .CSV Mimetypes,并且您可以通过将文件类型与接受类型的数组进行比较,在客户端上检查它,这样您就可以添加或删除适合您需求的方式。
// the list of the accepted types since we need it always it's better to
// make it global instead of local to the onchange litener, and even you can
// add other types dynamically as well;
const acceptedTypes = ["text/csv", "text/x-csv", "application/x-csv", "application/csv", "text/x-comma-separated-values", "text/comma-separated-values", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.ms-excel"];
document.querySelector("[type='file']").onchange = function() {
  if(!acceptedTypes.includes(this.files[0].type)) {
    console.log("This file is not allowed for upload");
    // if the file is not allowed then clear the value of the upload element
    this.value = "";
  }
};

如果您希望仅在用户拖放文件时出现此行为,则可以像这样自定义它。

const acceptedTypes = ["text/csv", "text/x-csv", "application/x-csv", "application/csv", "text/x-comma-separated-values", "text/comma-separated-values", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.ms-excel"];
// global variable to hold if the user has dragged the file or not
let isDragged = false;
// the `ondragover` gets triggered before the `onchange` event so it works as expected
document.querySelector("[type='file']").ondragover = function() {
  isDragged = true;
};
document.querySelector("[type='file']").onchange = function() {
  // if there was no drag then do nothing
  if(!isDragged) return;
  if(!acceptedTypes.includes(this.files[0].type)) {
    console.log("This file is not allowed for upload");
    // if the file is not allowed then clear the value of the upload element
    this.value = "";
  }
  isDragged = false;
};

0
你只需要添加一个事件监听器和函数,以接受或拒绝文件:
fileInput.addEventListener("change", func);

var func = function() {
  if(fileInput.files[0].type == /*insert your file types here*/) {
    //accept file and do stuff with it
  } else {
    //reject and tell user that is was rejected and why
  }
}

我不确定这是否适用于拖放文件输入,但我知道它适用于常规类型。每当文件更改时,都会调用change事件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接