元素中的浏览按钮时,我想限制可以从本机操作系统文件选择器中选择的文件类型。我觉得这是不可能的,但我想知道是否有 解决方案。我想只保留 HTML 和 JavaScript;请不要闪光。" /> 元素中的浏览按钮时,我想限制可以从本机操作系统文件选择器中选择的文件类型。我觉得这是不可能的,但我想知道是否有 解决方案。我想只保留 HTML 和 JavaScript;请不要闪光。"> 元素中的浏览按钮时,我想限制可以从本机操作系统文件选择器中选择的文件类型。我觉得这是不可能的,但我想知道是否有 解决方案。我想只保留 HTML 和 JavaScript;请不要闪光。" />
ChatGPT解决这个技术问题 Extra ChatGPT

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

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

它很容易使用 PHP,但我不知道你是否可以使用它,所以我不会发布代码。
我可以,但我有一个使用 JavaScript 的解决方案——它消除了上传文件然后得到“错误文件!”的烦恼。错误。
另请参阅最近的问题:stackoverflow.com/questions/181214/…
需要注意的一件事是,虽然它不是很好的验证,但在用户浏览它们时,accept 会将可见文件限制为已接受的文件(至少在某些浏览器中......)。因此,这更像是一种 UI 人机工程学功能,而不是验证功能。

S
Sachin Joseph

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

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

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

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

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

您还可以在 MIME 类型中使用星号。例如:

W3C recommends 作者在 accept 属性中指定 MIME 类型及其对应的扩展。因此,最佳方法是:

相同的 JSFiddle:here

参考: List of MIME-types

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

这里有 three good reads on文件上传和安全。

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


@Sandesire 我认为您不能限制 HTML 中的文件大小。正如您所建议的,可以使用 JavaScript。
从我个人的经验来看,这似乎是一个很好的答案,单独的 mime 类型不适用于所有浏览器。
顺便说一句,accept 在 Edge:stackoverflow.com/questions/31875617/… 中仍然不起作用。更多详情:wpdev.uservoice.com/forums/257854-microsoft-edge-developer/…
我希望我们也可以选择排除文件,例如 exclude="exe"。 ¯_(ツ)_/¯
为了进一步阐明 Edge 行为(根据我的测试),它将根据您指定的内容添加不同的过滤器,但是 a)它没有捆绑,因此它将每个扩展程序列为单独的选项,并且 b)它总是会添加一些 in-如前所述,构建 .html 和 c) 等扩展名,它将始终预先选择 (*)。在大多数情况下,这使它变得一团糟而且毫无用处。我对 uservoice 链接进行了投票,希望他们迟早会听到。
C
Community

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

例如:

HTML5 spec 中阅读更多信息

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

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

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


如需更多信息,请参阅 stackoverflow.com/questions/181214/…
尽管确实不可能阻止用户最终选择任何类型的文件,但如今,您可以利用 HTML5 File API 并在所选文件实际上传到服务器之前使用它进行上传,包括检测它的类型、大小等等。试试看。它非常易于使用,但功能强大且有用。
d
daaawx

您可以使用 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');休息;默认值:警报('不允许'); this.value = ''; } };

JSFiddle


@joe,这是一个示例……它可以扩展到您想要允许的任何扩展。
是的,你可以。但你没有!也许有人已经复制了它!那么具有正确 mime 类型但没有扩展名的文件呢?
@Joe ..好吧..我尝试提供方向和合理的逻辑。未针对每种情况完全实施解决方案。我相信观众在从网络复制/粘贴代码时会使用常识;)
“Some.File.jpg”怎么样?也许该正则表达式行需要阅读: var ext = this.value.match(/\.([^.]+)$/)[1];
这种方法的问题是,即使它没有以该扩展名结尾,从技术上讲,它仍然可能是 jpeg。扩展 !== 哑剧类型
P
Pablo Santa Cruz

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

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

就像是:

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

HTML 代码:

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

有一个完全有效的 html 属性,所以它是可能的。它只是不受浏览器的尊重,但那是一个标准化问题。以及在不受保护的标记中处理客户端的任何东西都不能限制任何东西 java 脚本不是解决方案。
很好的一点。我将添加第二个 PHP 检查器以防万一。不能太小心!
好吧,如果我也使用 PHP 验证脚本也没有什么坏处,所以我会同时使用这两个脚本。
@Joe:不要再说我的回答很烂! :-) 无论如何,这不是一个完美的解决方案。正如我在开头所说的那样:“不可能”做 OP 想要的。但是,如果您只让他/她选择具有某些扩展名的文件,则可以为用户提供一定程度的帮助。 REAL 文件类型验证必须在服务器端完成。
@JoeHopfgartner:伙计,你在这里对巴勃罗过于苛刻了。客户端验证在很多地方完成,虽然不是万无一失的(应该 [b]always[/b] 包括服务器端验证)它可以为用户节省相当长的时间(对于愚蠢的扩展检查等没有回发)。虽然 Pablo 给出的脚本并不完美,但它只是作为如何解决这个问题的一个例子......也许你应该给微软的技术人员发电子邮件,要求他们从他们的 ASP.NET 验证器中删除客户端验证,因为对你来说都是垃圾……
z
zzzzBov

从技术上讲,您可以在 input 元素上指定 accept attribute(在 html5 中替代),但它没有得到适当的支持。


W3Schools 浏览器支持失败!真的很可惜。这也是一个安全问题——人们可以破解客户端代码并上传他们想要的任何内容。
诚然,最好不要将其用于安全性,但它肯定有助于支持它的浏览器的可用性。用户只会看到网站允许的文件(而不是他们可能在同一文件夹中的所有其他垃圾),并且他们不必经历整个上传过程就会得到错误,他们会立即知道。编码人员应该使用它。
M
Max Hesari

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

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

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

2.Filter based on "file type" 这里的"accept"属性只允许你选择一个"image/jpeg"类型的文件。

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

重要提示:我们可以更改或删除文件的扩展名,而无需更改 meme 类型。例如,可以有一个没有扩展名的文件,但这个文件的类型可以是“image/jpeg”。所以这个文件不能通过 accept=".jpeg" 过滤器。但它可以通过accept="image/jpeg"。

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

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

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

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

b
bpross

我知道这有点晚了。

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

k
kiranvj

input 标记与 accept 属性一起使用

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

点击here for the latest browser compatibility table

现场演示here

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

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

现场演示here

https://i.stack.imgur.com/FWFiw.png


谢谢!在 Win10 上的 Chrome 中,如果我使用 accept="image/*",它会在文件选择器中显示“图像文件”而不是“自定义文件”,这对最终用户来说很好。
但用户可以更改它并上传其他扩展文件
@PrashantPrajapati 是的,浏览器就是这样制作的,服务器中应该有相应的验证。浏览器功能只是为了更好的用户体验。
M
Mike Mackintosh

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

如果您想开始使用服务器端验证,请查看 this basic tut。有关整个教程,请访问 this page

祝你好运!


S
Sachin Joseph

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

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

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


I
Imran Javed

我可能会建议以下内容:

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

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

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

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


这就是我一直在寻找的:accept=".bmp" 在 chrome 上运行良好。
Z
Zobris

在之前使用 accept 属性的答案的基础上,您可以使用 File API 完成此操作。如果您使用 FileReader 进行一些本地解析或数据处理,这也使您可以访问文件内容。

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

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

接下来我们需要监听输入元素上的“更改”事件。

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 + ' 不是 .txt 文件。'); } } });

现代浏览器很好地支持文件 API。通过将此与接受属性相结合,您可以轻松过滤本地用户可以在上传中选择的内容并提供有用的反馈。如果您正在上传文件,您仍应在后端检查并验证文件类型。