HTML <input type='file'> 应用过滤器

Posted

技术标签:

【中文标题】HTML <input type=\'file\'> 应用过滤器【英文标题】:HTML <input type='file'> apply a filterHTML <input type='file'> 应用过滤器 【发布时间】:2011-04-01 01:42:10 【问题描述】:
<input type='file' name='userFile'>

现在当我单击浏览按钮时,浏览对话框将显示所有文件...如果我想过滤文件类型该怎么办?

仅图像或 .png & .jpg & .gifs 仅 Office 文件,如 .doc & .docx & .pps

怎么做...

【问题讨论】:

【参考方案1】:

我想你正在寻找接受参数。试试这个作品

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

【讨论】:

【参考方案2】:

文件输入控件上有一个“接受”属性,您可以在其中指定所需的文件类型。 不过,据我所见,许多浏览器喜欢忽略它——可以指定的文件类型是 MIME 类型,因此严格正确的浏览器必须查看每个文件而不考虑扩展名,看看它是否是一张图片(如果是,它是什么类型)。

更新: 似乎 Windows 上每个主要浏览器的至少某些版本现在至少提供了对 accept 属性的一些支持。 (甚至 IE 也支持它,从版本 10 开始。)但是,依赖它还为时过早,因为 IE 8 和 9 仍然不支持它。总的来说,支持有点参差不齐。

Chrome 似乎得到了全面支持。它使用自己的内置类型列表以及系统的......因此,如果其中任何一个定义了类型,Chrome 就会知道要显示哪些文件。 IE 10 很好地支持文件扩展名,并且很好地支持 MIME 类型。它似乎只使用系统的 MIME 类型到扩展名的映射,但是......这基本上意味着如果用户计算机上的某些内容没有使用正确的 MIME 类型注册这些扩展名,IE 将不会显示这些 MIME 类型的文件。 Opera 似乎只支持 MIME 类型——以至于扩展实际上禁用了过滤器——而且文件选择器的 UI 很糟糕。您必须选择一种类型才能查看该类型的文件。 Firefox 似乎只支持有限的一组类型,并忽略其他类型和扩展。 我没有 Safari,也不打算下载它。如果有人可以记录 Safari 的支持... 对 safari 的部分支持。 http://caniuse.com/#search=accept

您应该考虑添加该属性,以便支持它的浏览器可以帮助用户更轻松地找到正确的文件。但我仍然建议您在选择文件后检查文件名,如果上传的文件扩展名错误,则会显示错误消息。

当然,一定要让服务器仔细检查文件类型是否正确。文件扩展名只是一种命名约定,很容易被颠覆。即使我们可以信任浏览器(我们不能),即使它确实尝试按照您的要求过滤内容(它可能不会),它实际上验证该 .doc 文件确实是一个Word 文档在 nil 旁边。

【讨论】:

"任何主流浏览器都不正确支持接受属性。" (引自w3schools.com/TAGS/att_input_accept.asp) 引用页面现在显示“所有主流浏览器都支持接受属性,除了 Internet Explorer 和 Safari。” 在 Chrome 中为 application/pdf 工作。对于 Firefox,请参阅 this bug ticket。对于 IE,谁在乎 IE。 @mattblang:运行大型网站的人关心 IE。 :) 它在市场的 1/5 到 1/2 之间(取决于你问谁)。【参考方案3】:

它应该使用MIME_type: 例如

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

这将只接受*.xlsx 文件类型...

有关 mime 类型的列表,请查看以下链接:http://www.bitsandpix.com/entry/microsoft-office-2007-2010-docx-xlsx-pptx-mime-type-to-avoid-the-zip-issue/

【讨论】:

【参考方案4】:

您无法控制可以选择哪些文件,但您可以在选择文件后使用 javascript 读取文件名。然后,如果文件类型错误,您可以显示警告和/或禁用提交按钮。但是,请记住,您不能依靠扩展名来告诉您文件是否真的是正确的类型。它只应被视为一种方式,以帮助那些可能在发现您不支持该文件类型之前浪费时间上传大文件的用户。

这里有一些示例代码可以做到这一点。它使用 jQuery,但你也可以用普通的 javascript 做同样的事情。

$(function() 
    $('#inputId').change( function() 
        var filename = $(this).val();
        if ( ! /\.txt$/.test(filename)) 
            alert('Please select a text file');
        
    );
);

【讨论】:

如何将它用于多种文件类型??【参考方案5】:

您可以使用 JavaScript。考虑到使用 JavaScript 执行此操作的最大问题是重置输入文件。好吧,这仅限于 JPG(对于其他格式,您必须更改 mime type 和 magic number):

<form id="form-id">
  <input type="file" id="input-id" accept="image/jpeg"/>
</form>

<script type="text/javascript">
    $(function()
        $("#input-id").on('change', function(event) 
            var file = event.target.files[0];
            if(file.size>=2*1024*1024) 
                alert("JPG images of maximum 2MB");
                $("#form-id").get(0).reset(); //the tricky part is to "empty" the input file here I reset the form.
                return;
            

            if(!file.type.match('image/jp.*')) 
                alert("only JPG images");
                $("#form-id").get(0).reset(); //the tricky part is to "empty" the input file here I reset the form.
                return;
            

            var fileReader = new FileReader();
            fileReader.onload = function(e) 
                var int32View = new Uint8Array(e.target.result);
                //verify the magic number
                // for JPG is 0xFF 0xD8 0xFF 0xE0 (see https://en.wikipedia.org/wiki/List_of_file_signatures)
                if(int32View.length>4 && int32View[0]==0xFF && int32View[1]==0xD8 && int32View[2]==0xFF && int32View[3]==0xE0) 
                    alert("ok!");
                 else 
                    alert("only valid JPG images");
                    $("#form-id").get(0).reset(); //the tricky part is to "empty" the input file here I reset the form.
                    return;
                
            ;
            fileReader.readAsArrayBuffer(file);
        );
    );
</script>

考虑到这是在最新版本的 Firefox 和 Chrome 以及 IExplore 10 上测试的。

For a complete list of mime types see Wikipedia.

For a complete list of magic number see Wikipedia.

【讨论】:

【参考方案6】:

对于大多数文件过滤情况,我为客户端验证提供了一种简单的方法。其实很简单。现在,在你去尝试实现它之前,了解服务器必须检查这个文件,因为在有人更改 .js 甚至 html 的情况下,javascript 和 HTML 过滤不是确定的事情。 我没有包括所有实际脚本,因为我喜欢看到其他人使用创造性思维来实现这些概念,但在找到更好的答案之前,这些步骤似乎有效:

创建一个查找输入并处理它的 js 对象。

调用一个函数,例如 AjaxControlToolKit 的 AsyncFileUpload 控件的 OnClientUploadComplete。

在此函数内部,声明一个布尔变量:bIsAccepted(设置为 false)和字符串 sFileName(从 args 获取文件名后)。

在 if..else 语句中,

if(sFilename.indexOf(".(acceptedExtension1)") ||
   sFileName.indexOf(".(AcceptedExtension2)") )

   bIsAccepted = true;

else

   bIsAccepted = false;

然后

if(bIsAccepted)

//Process Data

在服务器上,设置接受的文件扩展名列表并循环处理和类似的处理将使过程具有凝聚力和一致性,有效地允许 UI 和代码隐藏在几乎所有情况下过滤文件类型。

鉴于可以通过将名称更改为具有不同的文件扩展名作为名称的一部分来绕过这一点,因此在提交给服务器进行进一步处理之前,还应检查 mime 类型。

            [http://www.webmaster-toolkit.com/mime-types.shtml][1]

希望这会有所帮助!

【讨论】:

(1) 建议:与其做.indexOf(each hard-coded extension),不如取输入控件的accept属性的值,用,\s*分割,然后检查你得到的数组的每个成员.此时,您至少实现了accept 的过滤行为(即使您无法伪造 UI)。 (2) 在客户端,MIME 类型并不比扩展更可靠——浏览器不太可能打开文件并验证幻数等。它根据系统报告的 MIME 类型和/或它自己的内部扩展类型映射。【参考方案7】:

您应该使用使用嵌入式 Flash 的 one of the plugins,因为您无法使用纯 javascript 来做到这一点

【讨论】:

谢谢,但不,谢谢......我宁愿在选择文件类型后检查它......它会为我节省很多工作 +1 因为这是唯一可行的解​​决方案(尽管发布一些实际链接而不是可以更改的 Google 搜索会更好)。 @Moon,无论如何您都需要在之后检查文件类型(即上传后)......选择后您唯一可以在本地做的就是检查文件扩展名,这不是实际文件类型的 100% 可靠指标。 @Pekka웃:从 HTML 5 开始,许多浏览器实际上可以read the bytes of a selected file。在 IE 【参考方案8】:

使用 MVC,我们可以将上传限制为仅限 zip 文件

.HtmlAttributes(new  accept = ".zip*" )

【讨论】:

以上是关于HTML <input type='file'> 应用过滤器的主要内容,如果未能解决你的问题,请参考以下文章

<input type="file" /> 的 HTML 助手

jQuery动态添加<input type="file">

h5 input type=file 图片预览

自定义上传按钮 <input type="file" name = "file"/> (将file隐藏在button下)

我们可以改变 <input type="file"> 样式吗? [复制]

html input type=file -- 从 iCloud 中选择一个文件