Html 使用 <input type="file"> 时限制文件格式?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4328947/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 05:32:44  来源:igfitidea点击:

Limit file format when using <input type="file">?

htmlfiletypes

提问by Bojangles

I'd like to restrict the type of file that can be chosen from the native OS file chooser when the user clicks the Browse button in the <input type="file">element in HTML. I have a feeling it's impossible, but I'd like to know if there isa solution. I'd like to keep solely to HTML and JavaScript; no Flash please.

当用户单击<input type="file">HTML 元素中的浏览按钮时,我想限制可以从本机操作系统文件选择器中选择的文件类型。我有一种感觉,这是不可能的,但我想知道是否有一个解决方案。我想只使用 HTML 和 JavaScript;请不要闪光灯。

回答by Sachin Joseph

Strictly speaking, the answer is no. A developer cannotprevent a user from uploading files of any type or extension.

But still, the acceptattribute of <input type = "file">can help to provide a filter in the file select dialog box of the OS. For example,

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

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

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

should provide a way to filter out files other than .xls or .xlsx. Although the MDNpage for inputelement always said that it supports this, to my surprise, this didn't work for me in Firefox until version 42. This works in IE 10+, Edge, and Chrome.

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

So, for supporting Firefox older than 42 along with IE 10+, Edge, Chrome, and Opera, I guess it's better to use comma-separated list of MIME-types:

因此,为了支持 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) behavior: The file type filter dropdown shows the file types mentioned here, but is not the default in the dropdown. The default filter is All files (*).]

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

You can also use asterisks in MIME-types. For example:

您还可以在 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 recommendsauthors to specify both MIME-types and corresponding extensions in the acceptattribute. So, the bestapproach is:

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 of the same: here.

JSFiddle 相同:here

Reference:List of MIME-types

IMPORTANT:Using the acceptattribute only provides a way of filtering in the files of types that are of interest. Browsers still allow users to choose files of any type. Additional (client-side) checks should be done (using JavaScript, one way would be this), and definitely file types MUST be verified on the server, using a combination of MIME-type using both the file extension and its binary signature (ASP.NET, PHP, Ruby, Java). You might also want to refer to thesetablesfor file types and their magic numbers, to perform a more robust server-side verification.

Here are threegoodreadson file-uploads and security.

参考:MIME 类型列表

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

以下是关于文件上传和安全性的三个很好的读物

EDIT:Maybe file type verification using its binary signature can also be done on client side using JavaScript (rather than just by looking at the extension) using HTML5 File API, but still, the file must be verified on the server, because a malicious user will still be able to upload files by making a custom HTTP request.

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

回答by The Surrican

There is the accept attribute for the input tag. However, it is not reliable in any way. Browsers most likely treat it as a "suggestion", meaning the user will, depending on the file manager as well, have a pre-selection that only displays the desired types. They can still choose "all files" and upload any file they want.

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

For example:

例如:

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

Read more in the HTML5 spec

HTML5 规范中阅读更多内容

Keep in mind that it is only to be used as a "help" for the user to find the right files. Every user can send any request he/she wants to your server. You always have to validated everything server-side.

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

So the answer is: noyou cannot restrict, but you canset a pre-selection but you cannotrely on it.

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

Alternatively or additionally you can do something similar by checking the filename (value of the input field) with JavaScript, but this is nonsense because it provides no protection and also does not ease the selection for the user. It only potentially tricks a webmaster into thinking he/she is protected and opens a security hole. It can be a pain in the ass for users that have alternative file extensions (for example jpeg instead of jpg), uppercase, or no file extensions whatsoever (as is common on Linux systems).

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

回答by Gabriele Petrioli

You can use the changeevent to monitor what the user selects and notify them at that point that the file is not acceptable. It does not limit the actual list of files displayed, but it is the closest you can do client-side, besides the poorly supported acceptattribute.

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

JSFiddle

回答by Pablo Santa Cruz

Yes, you are right. It's impossible with HTML. User will be able to pick whatever file he/she wants.

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

You could write a piece of JavaScriptcode to avoid submitting a file based on its extension. But keep in mind that this by no means will prevent a malicious user to submit any file he/she really wants to.

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

Something like:

就像是:

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:

HTML代码:

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

回答by zzzzBov

Technically you can specify the acceptattribute(alternative in html5) on the inputelement, but it's not properly supported.

从技术上讲,您可以在元素上指定accept属性(替代html5input,但它没有得到正确支持。

回答by kiranvj

Use inputtag with acceptattribute

使用inputaccept属性的标签

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

Click here for the latest browser compatibility table

单击此处获取最新的浏览器兼容性表

Live demo here

现场演示在这里

To select only image files, you can use this accept="image/*"

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

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

Live demo here

现场演示在这里

Only gif, jpg and png will be shown, screen grab from Chrome version 44Only gif, jpg and png will be shown, screen grab from Chrome version 44

Only gif, jpg and png will be shown, screen grab from Chrome version 44仅显示 gif、jpg 和 png,Chrome 版本 44 的屏幕抓取

回答by bpross

I know this is a bit late.

我知道这有点晚了。

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

回答by Trufa

You could actually do it with javascript but remember js is client side, so you would actually be "warning users" what type of files they can upload, if you want to AVOID (restrict or limit as you said) certain type of files you MUST do it server side.

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

Look at this basic tutif you would like to get started with server side validation. For the whole tutorial visit this page.

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

Good luck!

祝你好运!

回答by svg

As mentioned in previous answers we cannot restrict user to select files for only given file formats. But it's really handy to use the accept tag on file attribute in html.

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

As for validation, we have to do it at the server side. We can also do it at client side in js but its not a foolproof solution. We must validate at server side.

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

For these requirements I really prefer struts2 Java web application development framework. With its built-in file upload feature, uploading files to struts2 based web apps is a piece of cake. Just mention the file formats that we would like to accept in our application and all the rest is taken care of by the core of framework itself. You can check it out at struts official site.

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

回答by Imran Javed

I may suggest following:

我可能建议如下:

  • If you have to make user select any of image files by default, the use accept="image/*"

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

  • if you want to restrict to specific image types then use accept="image/bmp, image/jpeg, image/png"

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

  • if you want to restrict to specific types then use accept=".bmp, .doc, .pdf"

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

  • You cannot restrict user to change file filer to all files, so always validate file type in script and server

  • 如果您必须让用户默认选择任何图像文件,请使用 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" />

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