协慌网

登录 贡献 社区

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

<input type="file">元素中的 “浏览” 按钮时,我想限制可以从本机 OS 文件选择器选择的文件类型。我有一种感觉,这是不可能的,但我想知道是否一个解决方案。我只想保留 HTML 和 JavaScript;请不要使用 Flash。

答案

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

但是, <input type = "file"> 的 accept属性仍然可以帮助在 OS 的 “文件选择” 对话框中提供过滤器。例如,

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

应该提供一种过滤掉. xls 或. xlsx 以外的文件的方法。尽管input元素的 MDN页面始终表示支持此功能,但令我惊讶的是,直到 42 版本,此功能才在 Firefox 中对我不起作用。它在 IE 10 +,Edge 和 Chrome 中均有效。

因此,为了支持 IE 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 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,一种方法是this ),并且绝对必须在服务器上验证文件类型,同时使用同时使用文件扩展名和其二进制签名( ASP)的 MIME 类型。 .NETPHPRubyJava )。您可能还需要参考这些以获取文件类型及其魔术数字,以执行更可靠的服务器端验证。

这里有3 个良好的读取上的文件上传和安全性。

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

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

例如:

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

阅读HTML5 规范中的更多内容

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

因此,答案是:不,不能限制,但是您可以设置预选择,但不能依靠它。

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

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