【发布时间】:2011-04-01 01:42:10
【问题描述】:
<input type='file' name='userFile'>
现在当我单击浏览按钮时,浏览对话框将显示所有文件...如果我想过滤文件类型该怎么办?
- 仅图像或 .png & .jpg & .gifs
- 仅 Office 文件,如 .doc & .docx & .pps
怎么做...
【问题讨论】:
标签: html forms filefilter
<input type='file' name='userFile'>
现在当我单击浏览按钮时,浏览对话框将显示所有文件...如果我想过滤文件类型该怎么办?
怎么做...
【问题讨论】:
标签: html forms filefilter
我想你正在寻找接受参数。试试这个作品
<input type="file" accept="image/*" />
【讨论】:
文件输入控件上有一个“接受”属性,您可以在其中指定所需的文件类型。 不过,据我所见,许多浏览器喜欢忽略它——可以指定的文件类型是 MIME 类型,因此严格正确的浏览器必须查看每个文件而不考虑扩展名,看看它是否是一张图片(如果是,它是什么类型)。
更新: 似乎 Windows 上每个主要浏览器的至少某些版本现在至少提供了对 accept 属性的一些支持。 (甚至 IE 也支持它,从版本 10 开始。)但是,依赖它还为时过早,因为 IE 8 和 9 仍然不支持它。总的来说,支持有点参差不齐。
您应该考虑添加该属性,以便支持它的浏览器可以帮助用户更轻松地找到正确的文件。但我仍然建议您在选择文件后检查文件名,如果上传的文件扩展名错误,则会显示错误消息。
当然,一定要让服务器仔细检查文件类型是否正确。文件扩展名只是一种命名约定,很容易被颠覆。即使我们可以信任浏览器(我们不能),即使它确实尝试按照您的要求过滤内容(它可能不会),它实际上验证该 .doc 文件确实是一个Word 文档在 nil 旁边。
【讨论】:
application/pdf 工作。对于 Firefox,请参阅 this bug ticket。对于 IE,谁在乎 IE。
它应该使用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/
【讨论】:
您无法控制可以选择哪些文件,但您可以在选择文件后使用 javascript 读取文件名。然后,如果文件类型错误,您可以显示警告和/或禁用提交按钮。但是,请记住,您不能依靠扩展名来告诉您文件是否真的是正确的类型。它只应被视为一种方式,以帮助那些可能在发现您不支持该文件类型之前浪费时间上传大文件的用户。
这里有一些示例代码可以做到这一点。它使用 jQuery,但你也可以用普通的 javascript 做同样的事情。
$(function() {
$('#inputId').change( function() {
var filename = $(this).val();
if ( ! /\.txt$/.test(filename)) {
alert('Please select a text file');
}
});
});
【讨论】:
您可以使用 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 上测试的。
【讨论】:
对于大多数文件过滤情况,我为客户端验证提供了一种简单的方法。其实很简单。现在,在你去尝试实现它之前,了解服务器必须检查这个文件,因为在有人更改 .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]
希望这会有所帮助!
【讨论】:
.indexOf(each hard-coded extension),不如取输入控件的accept属性的值,用,\s*分割,然后检查你得到的数组的每个成员.此时,您至少实现了accept 的过滤行为(即使您无法伪造 UI)。
您应该使用使用嵌入式 Flash 的 one of the plugins,因为您无法使用纯 javascript 来做到这一点
【讨论】:
使用 MVC,我们可以将上传限制为仅限 zip 文件
.HtmlAttributes(new { accept = ".zip*" })
【讨论】: