使用<输入类型="文件">时限制文件格式?

我想限制当用户单击超文本标记语言<input type="file">元素中的浏览按钮时,可以从本机操作系统文件选择器中选择的文件类型。我有一种感觉,这是不可能的,但我想知道是否有的解决方案。我想只保留超文本标记语言和JavaScript;没有Flash。

719210 次浏览

是的,你说得对。超文本标记语言是不可能的。用户可以选择他/她想要的任何文件。

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

类似:

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

超文本标记语言代码:

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

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

例如:

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

阅读更多HTML5规范

请记住,它仅用作用户找到正确文件的“帮助”。每个用户都可以向您的服务器发送他/她想要的任何请求。您必须始终验证服务器端的所有内容。

所以答案是:不能限制,但你可以设置了一个预选,但你不能依赖它。

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

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

如果您想开始服务器端验证,请查看这个基本的tut。对于整个教程,请访问此页面

祝你好运!

从技术上讲,您可以在input元素上指定#0属性html5中的替代方案),但它没有得到正确的支持。

您可以使用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

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

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

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

严格来说,答案是。开发人员不能阻止用户上传任何类型或扩展名的文件。

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

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

应该提供一种过滤掉. xls或. xlsx以外的文件的方法。尽管input元素的MDN页面总是说它支持这一点,但令我惊讶的是,这在Firefox版本42之前对我不起作用。这适用于IE 10+、Edge和Chrome。

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

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

[Edge(EdgeHTML)行为:文件类型过滤器下拉列表显示此处提到的文件类型,但不是下拉列表中的默认类型。默认过滤器为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建议作者在accept属性中指定MIME类型及其相应的扩展。因此,最好方法是:

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

相同的jsfiddle:这里.

参考:MIME类型列表

重要事项:使用accept属性仅提供了一种过滤感兴趣类型的文件的方法。浏览器仍然允许用户选择任何类型的文件。应该进行额外的(客户端)检查(使用JavaScript,一种方法是这个),并且肯定是文件类型必须在服务器上验证,使用MIME类型的组合使用文件扩展名及其二进制签名(ASP.NETphprubyJava)。您可能还想参考这些的文件类型及其重要事项:0,以执行更强大的服务器端验证。

以下是关于文件上传和安全性的阅读

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

我知道这有点晚了。

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;}

使用input标签和accept属性

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

点击这里是最新的浏览器兼容性表

现场演示这里

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

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

现场演示这里

只有gif, jpg和png会显示,从Chrome版本44抓取屏幕只显示gif,jpg和png,从Chrome版本44抓取屏幕

我建议如下:

  • 如果您必须让用户默认选择任何图像文件,请使用接受="图像/*"

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

  • 如果您想限制特定的图像类型,请使用接受="图像/bmp,图像/jpeg,图像/png"

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

  • 如果您想限制为特定类型,请使用接受=". bmp,. doc,. pdf"

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

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

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

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

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

2.根据“文件类型”进行过滤在这里,“接受”属性只允许您选择“图像/jpeg”类型的文件。

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

重要提示:我们可以在不更改meme类型的情况下更改或删除文件的扩展名。例如,可以有一个没有扩展名的文件,但此文件的类型可以是“图像/jpeg”。所以这个文件不能传递接受=“. jpeg”过滤器。但它可以传递接受=“图像/jpeg”。

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

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

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

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

在前面使用接受属性的答案的基础上,您可以使用文件API来完成这一点。如果您使用文件读取器进行一些本地解析或数据处理,这也允许您访问文件内容。

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

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

接下来,我们需要监听输入元素上的'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>

File API is very well supported for modern browsers. By combining this with the accept attribute you can easily filter what the local user can select in an upload and provide useful feedback. If you are uploading the file, you should still check and validate the file type on your backend.