使用<input type =“file”/>时限制文件格式?

时间:2010-12-01 20:44:41

标签: html file types

当用户单击HTML中<input type="file">元素中的“浏览”按钮时,我想限制可从本机OS文件选择器中选择的文件类型。我觉得这是不可能的,但我想知道是否是一个解决方案。我想完全依赖于HTML和JavaScript;请不要闪光。

12 个答案:

答案 0 :(得分:880)

严格来说,答案是。开发人员无法阻止用户在本机操作系统文件选择对话框中选择任何类型或扩展名的文件。

但是, accept <input type = "file">属性可以帮助在操作系统的文件选择对话框中提供过滤器。例如,

<!-- (IE 10+, Edge, Chrome, Firefox 42+) -->
<input type="file" accept=".xls,.xlsx" />

应该提供一种过滤除.xls或.xlsx之外的文件的方法。虽然input元素的MDN页面始终表示它支持这一点,但令我惊讶的是,在版本42之前,这对我来说在Firefox中不起作用。这适用于IE 10 +,Edge和Chrome

因此,为了支持42岁以上的Firefox以及IE 10 +,Edge,Chrome和Opera,我想最好使用以逗号分隔的MIME类型列表:

<!-- (IE 10+, Edge, Chrome, Firefox) -->
<input type="file"
 accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" /> 

[ Edge 行为:文件类型过滤器下拉列表显示此处提到的文件类型,但不是下拉列表中的默认值。默认过滤器为All files (*)。]

您也可以在MIME类型中使用星号。例如:

<input type="file" accept="image/*" /> <!-- all image types --> 
<input type="file" accept="audio/*" /> <!-- all audio types --> 
<input type="file" accept="video/*" /> <!-- all video types --> 

W3C recommends 作者在accept属性中指定MIME类型和相应的扩展名。因此,最佳方法是:

<!-- Right approach: Use both file extensions and corresponding MIME-types. -->
<!-- (IE 10+, Edge, Chrome, Firefox) -->
<input type="file"
 accept=".xls,.xlsx, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" /> 

同样的JSFiddle:here

参考: List of MIME-types

重要信息:使用accept属性仅提供了一种过滤感兴趣类型的文件的方法。浏览器仍然允许用户选择任何类型的文件。应该进行额外的(客户端)检查(使用JavaScript,一种方式是this),并确保文件类型 必须在服务器上验证 ,使用文件扩展名及其二进制签名(ASP.NETPHPRubyJava)的MIME类型组合。您可能还需要参考these tables了解文件类型及其magic numbers,以执行更强大的服务器端验证。

以下是关于文件上传和安全性的three good reads

编辑:可以使用其二进制签名进行文件类型验证也可以在客户端使用JavaScript(而不是仅通过查看扩展名)使用HTML5文件API完成,但仍然是文件必须在服务器上验证,因为恶意用户仍然可以通过发出自定义HTTP请求来上传文件。

答案 1 :(得分:185)

输入标记有accept属性。但是,它在任何方面都不可靠。 浏览器最有可能将其视为“建议”,这意味着用户将根据文件管理器进行预选,仅显示所需类型。他们仍然可以选择“所有文件”并上传他们想要的任何文件。

示例:

<form>
  <input type="file" name="pic" id="pic" accept="image/gif, image/jpeg" />
</form>

html5 spec

中阅读更多内容

请记住,它只是用作“帮助”,以便用户找到正确的文件。 每个用户都可以向服务器发送他/她想要的任何请求。 你总是需要验证服务器端的所有内容。

答案是:没有无法限制,但你可以设置预选但你不能依赖它。

或者另外,您可以通过使用JavaScript检查文件名(输入字段的值)来执行类似操作,但这是无稽之谈,因为它不提供保护,也不会简化用户的选择。它只会欺骗网站管理员认为他/她受到保护并打开安全漏洞。对于具有替代文件扩展名(例如jpeg而不是jpg),大写或没有任何文件扩展名的用户来说,这可能是一种痛苦(在Linux系统中很常见)。

答案 2 :(得分:85)

您可以使用change事件来监控用户选择的内容,并在此时通知他们该文件不可接受。它不限制显示的实际文件列表,但除了支持不良的accept属性外,它是客户端最接近的文件。

var file = document.getElementById('someId');

file.onchange = function(e) {
  var ext = this.value.match(/\.([^\.]+)$/)[1];
  switch (ext) {
    case 'jpg':
    case 'bmp':
    case 'png':
    case 'tif':
      alert('Allowed');
      break;
    default:
      alert('Not allowed');
      this.value = '';
  }
};
<input type="file" id="someId" />

JSFiddle

答案 3 :(得分:45)

是的,你是对的。使用HTML是不可能的。用户可以选择他/她想要的任何文件。

您可以编写一段 JavaScript 代码,以避免根据其扩展名提交文件。但请记住,这绝不会阻止恶意用户提交他/她真正想要的任何文件。

类似的东西:

function beforeSubmit()
{
    var fname = document.getElementById("ifile").value;
    // check if fname has the desired extension
    if (fname hasDesiredExtension) {
        return true;
    } else {
        return false;
    }
}

HTML code:

<form method="post" onsubmit="return beforeSubmit();">
    <input type="file" id="ifile" name="ifile"/>
</form>

答案 4 :(得分:18)

从技术上讲,您可以在input元素上指定accept attributehtml5中的替代方案),但它不受支持。

答案 5 :(得分:9)

input标记与accept属性

一起使用
<input type="file" name="my-image" id="image" accept="image/gif, image/jpeg, image/png" />

点击here for the latest browser compatibility table

现场演示here

要仅选择图像文件,您可以使用此accept="image/*"

<input type="file" name="my-image" id="image" accept="image/*" />

现场演示here

Only gif, jpg and png will be shown, screen grab from Chrome version 44 只显示gif,jpg和png,从Chrome版本44获取屏幕

答案 6 :(得分:8)

我知道这有点晚了。

function Validatebodypanelbumper(theForm)
{
   var regexp;
   var extension =     theForm.FileUpload.value.substr(theForm.FileUpload1.value.lastIndexOf('.'));
   if ((extension.toLowerCase() != ".gif") &&
       (extension.toLowerCase() != ".jpg") &&
       (extension != ""))
   {
      alert("The \"FileUpload\" field contains an unapproved filename.");
      theForm.FileUpload1.focus();
      return false;
   }
   return true;
}

答案 7 :(得分:5)

你实际上可以用javascript来做但是记住js是客户端,所以你实际上是“警告用户”他们可以上传什么类型的文件,如果你想要避免(限制或限制你说)某种类型的你必须在服务器端做文件。

如果您想开始使用服务器端验证,请查看this basic tut。有关整个教程,请访问this page

祝你好运!

答案 8 :(得分:3)

我可能建议以下内容:

  • 如果您必须让用户默认选择任何图像文件,请使用accept =“ image / *”

    <input type="file" accept="image/*" />

  • 如果您想限制特定的图像类型,请使用accept =“ image / bmp,image / jpeg,image / png”

    <input type="file" accept="image/bmp, image/jpeg, image/png" />

  • 如果要限制为特定类型,请使用accept =“。bmp,.doc,.pdf”

    <input type="file" accept=".bmp, .doc, .pdf" />

  • 您不能限制用户将文件文件管理器更改为所有文件,因此请始终在脚本和服务器中验证文件类型

答案 9 :(得分:2)

如前面的答案中所述,我们不能限制用户仅为给定的文件格式选择文件。但是在html中使用文件属性上的accept标签真的很方便。

至于验证,我们必须在服务器端进行验证。我们也可以在js的客户端进行,但它不是一个万无一失的解决方案。我们必须在服务器端验证。

对于这些要求,我更喜欢struts2 Java Web应用程序开发框架。凭借其内置的文件上传功能,将文件上传到基于struts2的Web应用程序是一件小事。只需提及我们希望在我们的应用程序中接受的文件格式,其余所有内容都由框架本身的核心处理。你可以在struts官方网站上查看。

答案 10 :(得分:1)

您可以在文件选择框中使用“ accept”属性作为过滤器。 使用“接受”可帮助您根据输入文件的“后缀”或“ meme类型”来过滤输入文件

1。基于后缀的过滤器: 这里的“ accept”属性只允许选择扩展名为.jpeg的文件。

<input type="file" accept=".jpeg" />

2。基于“文件类型”的过滤器 在这里,“ accept”属性只允许选择“ image / jpeg”类型的文件。

<input type="file" accept="image/jpeg" />

重要提示:我们可以更改或删除文件的扩展名,而无需更改meme类型。例如,可以有一个没有扩展名的文件,但是此文件的类型可以是“ image / jpeg”。因此,此文件无法通过accept =“。jpeg”过滤器。但它可以传递accept =“ image / jpeg”。

3。我们可以使用*选择所有类型的文件类型。例如下面的代码允许选择所有类型的图像。例如“ image / png”或“ image / jpeg”或...。都允许。

<input type="file" accept="image/*" /> 

4。我们可以在选择属性中将cama(,)用作“或运算符”。例如,要允许所有类型的图像或pdf文件,我们可以使用以下代码:

<input type="file" accept="image/* , application/pdf" />

答案 11 :(得分:0)

基于之前使用 accept 属性的答案,您可以使用 File API 完成此操作。如果您使用 FileReader 进行一些本地解析或数据处理,这也使您可以访问文件内容。

首先创建一个 input 元素,在这里您可以将文件类型应用于 accept 属性,但在示例中它将允许您选择所有文件类型。

<input type="file" name="upload" accept="*" multiple>

接下来我们需要监听 input 元素上的 'change' 事件。

var upload = document.querySelector('input[type="file"]');
upload.addEventListener('change', function() {});

在函数内部,您将能够访问输入的文件对象。

var files = this.files

我们不能只迭代对象,因为它不是数组,但是我们可以使用 item() 函数从列表中访问我们的 File 对象。

for (var i = 0; i < files.length; i++) {
    var file = files.item(i);
}

现在我们有了 File 对象,我们可以访问它的名称和类型属性,并在此处进行文件检查。在这种情况下,我正在检查它是否是 .txt 文件,如果不是,则打印一条消息。您可以根据文件类型的正则表达式模式检查名称,或根据其 MIME 类型检查类型。

if (!file.name.match(/.txt$/i) || file.type != 'text/plain') {
    console.log(file.name + ' is not a .txt file.');
}

var upload = document.querySelector('input[type="file"]');
upload.addEventListener('change', function() {
    var files = this.files;
    for (var i = 0; i < files.length; i++) {
        var file = files.item(i);
        if (!file.name.match(/.txt$/i) || file.type != 'text/plain') {
            console.log(file.name + ' is not a .txt file.');
        }
    }
});
<input type="file" name="upload" accept="*" multiple>

文件 API 非常受现代浏览器的支持。通过将其与 accept 属性相结合,您可以轻松过滤本地用户可以在上传中选择的内容并提供有用的反馈。如果您要上传文件,您仍应在后端检查并验证文件类型。