<input type="file"> 按扩展名限制可选文件 [重复]

Posted

技术标签:

【中文标题】<input type="file"> 按扩展名限制可选文件 [重复]【英文标题】:<input type="file"> limit selectable files by extensions [duplicate] 【发布时间】:2011-08-13 09:12:27 【问题描述】:

如何通过扩展名限制可以使用 input type="file" 元素选择的文件?

我已经知道 accept 属性,但在 chrome 中,它确实通过定义的最后一个 MIME 类型(在本例中为“gif”)限制文件,而 FF4 甚至没有任何限制。

<input type="file" accept="image/jpg, image/gif">

我做错了什么还是有其他方法?

【问题讨论】:

【参考方案1】:
 function uploadFile() 
     var fileElement = document.getElementById("fileToUpload");
        var fileExtension = "";
        if (fileElement.value.lastIndexOf(".") > 0) 
            fileExtension = fileElement.value.substring(fileElement.value.lastIndexOf(".") + 1, fileElement.value.length);
        
        if (fileExtension == "odx-d"||fileExtension == "odx"||fileExtension == "pdx"||fileExtension == "cmo"||fileExtension == "xml") 
         var fd = new FormData();
        fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
        var xhr = new XMLHttpRequest();
        xhr.upload.addEventListener("progress", uploadProgress, false);
        xhr.addEventListener("load", uploadComplete, false);
        xhr.addEventListener("error", uploadFailed, false);
        xhr.addEventListener("abort", uploadCanceled, false);
        xhr.open("POST", "/post_uploadReq");
        xhr.send(fd);
        
        else 
            alert("You must select a valid odx,pdx,xml or cmo file for upload");
            return false;
        
       
      

试过了,效果很好

【讨论】:

如果您正在上传文件,请记住还要在服务器上验证文件类型,因为可以绕过客户端验证。【参考方案2】:

注意:这个答案来自 2011 年。当时这是一个非常好的答案,但截至 2015 年,大多数浏览器都支持原生 html 属性,因此(通常)不需要实现JS中的这种自定义逻辑。请参阅Edi's answer 和the docs。


在文件上传之前,您可以使用javascript检查文件的扩展名,如果不匹配则阻止提交。要上传的文件名存储在表单元素的“value”字段中。

这是一个简单的例子,它只允许上传以“.gif”结尾的文件:

<script type="text/javascript">
    function checkFile() 
        var fileElement = document.getElementById("uploadFile");
        var fileExtension = "";
        if (fileElement.value.lastIndexOf(".") > 0) 
            fileExtension = fileElement.value.substring(fileElement.value.lastIndexOf(".") + 1, fileElement.value.length);
        
        if (fileExtension.toLowerCase() == "gif") 
            return true;
        
        else 
            alert("You must select a GIF file for upload");
            return false;
        
    
</script>

<form action="upload.aspx" enctype="multipart/form-data" onsubmit="return checkFile();">
    <input name="uploadFile" id="uploadFile" type="file" />

    <input type="submit" />
</form>

但是,这种方法并非万无一失。 Sean Haddy 是正确的,您始终希望在服务器端进行检查,因为用户可以通过关闭 javascript 或在代码到达浏览器后编辑您的代码来击败您的 Javascript 检查。除了客户端检查之外,一定要检查服务器端。此外,我还建议检查服务器端的大小,这样用户就不会因为 2 GB 文件而使您的服务器崩溃(我不知道在不使用 Flash 或 Java 小程序或其他东西的情况下检查客户端的文件大小) )。

但是,使用我在这里给出的方法事先检查客户端仍然很有用,因为它可以防止错误并且对非严重的恶作剧有轻微的威慑作用。

【讨论】:

这是最好的答案。尽管您知道您肯定需要在服务器端正确检查文件,但这种客户端 JS 检查有利于可用性 - 意味着您可以及早警告用户可能出现的错误。 在比较之前你会想要一个 toLowerCase() @MrTristan 好建议。我已经添加了。 使用 IE 您可以使用 Scripting.FileSystemObject 检查文件大小,但您需要在客户端浏览器中允许不安全的 ActiveX。所以是的,没有“好”的方法。【参考方案3】:

简单的方法是:

<input type="file" accept=".gif,.jpg,.jpeg,.png,.doc,.docx">

适用于所有浏览器,IE9 除外。我没有在IE10+中测试过。

【讨论】:

accept 在 Firefox 中不起作用(从 31.0 和 32.0 开始) 在 FF 37.0 中测试。工作正常!。 在文件输入的“接受”下,还可以定义选择文件的一般类型。例如,如果您将“image/*”放在“accept”属性下,则限制将涵盖图像的所有标准文件格式(gif、jpeg 等),而不仅仅是扩展名的类型。此外,您可以组合预定义的类型和扩展。例如:“图像/*,.swf”。对于此示例,限制将包括所有标准图像文件和所有“.swf”文件。注意:用户始终可以从对话框的类型列表中选择“所有文件”... ;-) 这有助于为上传文件对话框提供一些过滤,但我绝对认为这也需要与服务器限制结合使用。 @clockw0rk 输入检查和安全性应始终在服务器端实施。接受功能的存在只是为了帮助用户快速过滤相关文件,而不必筛选数千个不相关的文件。【参考方案4】:

老实说,限制文件的最佳方式是在服务器端。人们可以在客户端欺骗文件类型,因此在服务器传输时获取完整的文件名,解析文件类型,然后返回消息通常是最好的选择。

【讨论】:

+1。另外,如果接收到的文件太大,我建议在服务器端代码中添加一些内容以停止上传。 @JoshuaCarmody 你建议如何处理服务器端的大文件(2gb 及以上)? @Allan 很大程度上取决于技术。 ASP.NET 有一个“最大请求大小”,您可以在 Web.config 中指定它。在其他语言中可以编写一个从输入流中读取请求并在达到一定字节数后停止的处理程序。真的取决于你的应用程序。如果您想了解更多详细信息,请发布一个单独的问题。 我认为两者都做比较好。向用户提供有关(不)可选择的文件的前馈,将节省一些挫败感。因为如果用户花半分钟精确选择他需要的文件,然后发现这一切都是徒劳的。你越早打电话越好。 -1。很好的建议,但问题并没有表明文件会上传到任何地方。它甚至根本没有暗示服务器的存在(例如在完全客户端应用程序的情况下)。如前所述,这个答案应该是评论。

以上是关于<input type="file"> 按扩展名限制可选文件 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

样式 <input type="file"> [重复]

如何重置 <input type = "file">

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

<input type="file"> 的事件 [重复]

从 <input type="file"> 上传文件

触发 <input type="file"/> 的 javascript 事件 onchange 事件