【问题标题】:Validation of file extension before uploading file上传文件前验证文件扩展名
【发布时间】:2011-05-13 04:26:52
【问题描述】:

我正在将图像上传到 servlet。通过检查文件头中的幻数,仅在服务器端验证上传的文件是否为图像。在将表单提交给 servlet 之前,有什么方法可以验证客户端的扩展?我一按回车就开始上传。

我在客户端使用 Javascript 和 jQuery。

更新: 我最终得到了服务器端验证,它读取字节并拒绝上传,如果它不是图像。

【问题讨论】:

  • 您正在使用 Uploadify,正如您之前的一个问题中所建议的那样,对吧?
  • 不,它停在 50-96 之间。多次尝试各种输入。而且,我当时也急于寻求解决方案。所以,我尝试了简单的jquery.ProgressBar.js。它有效,很好。 ### 那么,我可以使用uploadify 验证吗!!!
  • 我们不能简单地在输入标签中使用accept属性来确保用户选择指定格式的文件吗?

标签: javascript jquery validation file-upload


【解决方案1】:

可以只检查文件扩展名,但用户可以轻松地将 virus.exe 重命名为 virus.jpg 并“通过”验证。

对于它的价值,这里是检查文件扩展名并在不符合有效扩展名之一时中止的代码:(选择无效文件并尝试提交以查看警报)

var _validFileExtensions = [".jpg", ".jpeg", ".bmp", ".gif", ".png"];    
function Validate(oForm) {
    var arrInputs = oForm.getElementsByTagName("input");
    for (var i = 0; i < arrInputs.length; i++) {
        var oInput = arrInputs[i];
        if (oInput.type == "file") {
            var sFileName = oInput.value;
            if (sFileName.length > 0) {
                var blnValid = false;
                for (var j = 0; j < _validFileExtensions.length; j++) {
                    var sCurExtension = _validFileExtensions[j];
                    if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) {
                        blnValid = true;
                        break;
                    }
                }
                
                if (!blnValid) {
                    alert("Sorry, " + sFileName + " is invalid, allowed extensions are: " + _validFileExtensions.join(", "));
                    return false;
                }
            }
        }
    }
  
    return true;
}
<form onsubmit="return Validate(this);">
  File: <input type="file" name="my file" /><br />
  <input type="submit" value="Submit" />
</form>

注意,该代码将允许用户在不选择文件的情况下发送...如果需要,请删除行 if (sFileName.length &gt; 0) { 及其关联的右括号。该代码将验证表单中的任何文件输入,无论其名称如何。

这可以用 jQuery 用更少的行来完成,但我对“原始”JavaScript 已经足够熟悉了,最终结果是一样的。

如果您有更多文件,或者想要在更改文件时触发检查,而不仅仅是在表单提交中,请改用此类代码:

var _validFileExtensions = [".jpg", ".jpeg", ".bmp", ".gif", ".png"];    
function ValidateSingleInput(oInput) {
    if (oInput.type == "file") {
        var sFileName = oInput.value;
         if (sFileName.length > 0) {
            var blnValid = false;
            for (var j = 0; j < _validFileExtensions.length; j++) {
                var sCurExtension = _validFileExtensions[j];
                if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) {
                    blnValid = true;
                    break;
                }
            }
             
            if (!blnValid) {
                alert("Sorry, " + sFileName + " is invalid, allowed extensions are: " + _validFileExtensions.join(", "));
                oInput.value = "";
                return false;
            }
        }
    }
    return true;
}
File 1: <input type="file" name="file1" onchange="ValidateSingleInput(this);" /><br />
File 2: <input type="file" name="file2" onchange="ValidateSingleInput(this);" /><br />
File 3: <input type="file" name="file3" onchange="ValidateSingleInput(this);" /><br />

如果文件扩展名无效,这将显示警报并重置输入。

【讨论】:

  • 我想补充一点,使用“onSubmit”而不是“onChange”很麻烦——尤其是在使用“multiple”选项的情况下。每个文件都应在选择时进行检查,而不是在发布整个表单时进行检查。
  • @Devlsh 一个有趣的想法,也会在帖子中提到这一点。谢谢!
  • 非常感谢@Shadow Wizard 提供的这段代码。它对我帮助很大!
  • @garryman 如何失败?这里的问题没有提到该文件是必需的。如果在您的情况下,该文件是必填字段,您可以将行 var blnValid = false; 移动到 arrInputs 上的循环上方,然后在循环后检查变量 blnValid: 如果为 true,则让表单提交,否则显示警告该文件是必需的。
  • 查看我下面的答案
【解决方案2】:

对于请求的简单性,现有答案似乎都不够紧凑。检查给定的文件输入字段是否具有集合中的扩展名可以如下完成:

function hasExtension(inputID, exts) {
    var fileName = document.getElementById(inputID).value;
    return (new RegExp('(' + exts.join('|').replace(/\./g, '\\.') + ')$')).test(fileName);
}

因此示例用法可能是(其中upload 是文件输入的id):

if (!hasExtension('upload', ['.jpg', '.gif', '.png'])) {
    // ... block upload
}

或者作为一个 jQuery 插件:

$.fn.hasExtension = function(exts) {
    return (new RegExp('(' + exts.join('|').replace(/\./g, '\\.') + ')$')).test($(this).val());
}

示例用法:

if (!$('#upload').hasExtension(['.jpg', '.png', '.gif'])) {
    // ... block upload
}

.replace(/\./g, '\\.') 用于转义正则表达式的点,以便可以在不匹配任何字符的点的情况下传递基本扩展。

没有错误检查来保持它们的简短,大概如果你使用它们,你会确保输入首先存在并且扩展数组是有效的!

【讨论】:

  • 不错。请注意,这些脚本区分大小写。要解决这个问题,你需要给RexExp the "i" modifier, for example: return (new RegExp('(' + exts.join('|').replace(/\./g, '\\.') + ')$', "i")).test(fileName);
  • 有点难以阅读,但这意味着在正则表达式字符串()$')的末尾添加, "i"。这将添加对文件扩展名(.jpg、.JPG、.JPG 等)中任何大小写的支持
  • 谢谢你,Tedd,最好有不区分大小写的匹配。
【解决方案3】:
$(function () {
    $('input[type=file]').change(function () {
        var val = $(this).val().toLowerCase(),
            regex = new RegExp("(.*?)\.(docx|doc|pdf|xml|bmp|ppt|xls)$");

        if (!(regex.test(val))) {
            $(this).val('');
            alert('Please select correct file format');
        }
    });
});

【讨论】:

  • 谢谢,非常简单干净。
  • 如果你按下取消,它会触发警报。
  • 如果你有一个“文件”对象,使用file.name代替val():var val = $(file.name).toLowerCase(), ...
【解决方案4】:

我来到这里是因为我确信这里的答案都不是很……诗意:

function checkextension() {
  var file = document.querySelector("#fUpload");
  if ( /\.(jpe?g|png|gif)$/i.test(file.files[0].name) === false ) { alert("not an image!"); }
}
&lt;input type="file" id="fUpload" onchange="checkextension()"/&gt;

【讨论】:

  • 感谢这在 Angular 中几乎没有修改,谢谢
  • 对我来说效果很好,尽管在测试之前应该修剪名称中的任何尾随空格。 +1
【解决方案5】:

您是否使用输入类型=“文件”来选择上传文件?如果是的话,为什么不使用accept属性呢?

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

【讨论】:

  • 这个! accept="image/*" 在大多数情况下,这绝对是最明智的选择。
  • 很棒的提示!正是我需要的。
  • 点击浏览按钮后,在弹出窗口中,如果我们选择所有文件,它将显示所有文件,而不仅仅是图像
【解决方案6】:

检查文件是否被选中

       if (document.myform.elements["filefield"].value == "")
          {
             alert("You forgot to attach file!");
             document.myform.elements["filefield"].focus();
             return false;  
         }

检查文件扩展名

  var res_field = document.myform.elements["filefield"].value;   
  var extension = res_field.substr(res_field.lastIndexOf('.') + 1).toLowerCase();
  var allowedExtensions = ['doc', 'docx', 'txt', 'pdf', 'rtf'];
  if (res_field.length > 0)
     {
          if (allowedExtensions.indexOf(extension) === -1) 
             {
               alert('Invalid file Format. Only ' + allowedExtensions.join(', ') + ' are allowed.');
               return false;
             }
    }

【讨论】:

    【解决方案7】:

    我喜欢这个例子:

    <asp:FileUpload ID="fpImages" runat="server" title="maximum file size 1 MB or less" onChange="return validateFileExtension(this)" />
    
    <script language="javascript" type="text/javascript">
        function ValidateFileUpload(Source, args) {
            var fuData = document.getElementById('<%= fpImages.ClientID %>');
            var FileUploadPath = fuData.value;
    
            if (FileUploadPath == '') {
                // There is no file selected 
                args.IsValid = false;
            }
            else {
                var Extension = FileUploadPath.substring(FileUploadPath.lastIndexOf('.') + 1).toLowerCase();
                if (Extension == "gif" || Extension == "png" || Extension == "bmp" || Extension == "jpeg") {
                    args.IsValid = true; // Valid file type
                    FileUploadPath == '';
                }
                else {
                    args.IsValid = false; // Not valid file type
                }
            }
        }
    </script>
    

    【讨论】:

      【解决方案8】:

      如果您需要在输入字段中测试远程 url,您可以尝试使用您感兴趣的类型测试一个简单的正则表达式。

      $input_field = $('.js-input-field-class');
      
      if ( !(/\.(gif|jpg|jpeg|tiff|png)$/i).test( $input_field.val() )) {
        $('.error-message').text('This URL is not a valid image type. Please use a url with the known image types gif, jpg, jpeg, tiff or png.');
        return false;
      }
      

      这将捕获 .gif、.jpg、.jpeg、.tiff 或 .png 中的任何结尾

      我应该注意到,一些流行的网站,如 Twitter,会在其图片的末尾附加一个 size 属性。例如,即使它是有效的图像类型,下面的测试也会失败:

      https://pbs.twimg.com/media/BrTuXT5CUAAtkZM.jpg:large
      

      因此,这不是一个完美的解决方案。但它会让你走完大约 90% 的路。

      【讨论】:

        【解决方案9】:

        尝试使用 mimetype 比检查扩展名更好。因为,有时文件可以在没有它的情况下存在,并且在 linux 或 unix 系统中运行良好。

        所以,你可以试试这样的:

        ["image/jpeg", "image/png", "image/gif"].indexOf(file.type) > -1
        

        ["image/jpeg", "image/png", "image/gif"].includes(file.type)
        

        【讨论】:

          【解决方案10】:

          试试这个(对我有用)

            
            function validate(){
            var file= form.file.value;
                 var reg = /(.*?)\.(jpg|bmp|jpeg|png)$/;
                 if(!file.match(reg))
                 {
              	   alert("Invalid File");
              	   return false;
                 }
                 }
          <form name="form">
          <input type="file" name="file"/>
          <input type="submit" onClick="return validate();"/>
          </form>
          
               

          【讨论】:

            【解决方案11】:

            您可以使用可用于输入文件类型的accept 属性。 Checkout MDN documentation

            【讨论】:

            • 有了这个你仍然可以选择其他文件类型
            • @CésarLeón 是的。用户可以选择所有文件。如果您也想限制它,您需要进行手动验证。检查其他答案。
            【解决方案12】:

            另一个现在的例子来自Array.prototype.some()

            function isImage(icon) {
              const ext = ['.jpg', '.jpeg', '.bmp', '.gif', '.png', '.svg'];
              return ext.some(el => icon.endsWith(el));
            }
            
            console.log(isImage('questions_4234589.png'));
            console.log(isImage('questions_4234589.doc'));

            【讨论】:

              【解决方案13】:

              这里有一个更可重用的方式,假设你使用 jQuery

              库函数(不需要jQuery):

              function stringEndsWithValidExtension(stringToCheck, acceptableExtensionsArray, required) {
                  if (required == false && stringToCheck.length == 0) { return true; }
                  for (var i = 0; i < acceptableExtensionsArray.length; i++) {
                      if (stringToCheck.toLowerCase().endsWith(acceptableExtensionsArray[i].toLowerCase())) { return true; }
                  }
                  return false;
              }
              
              
              String.prototype.startsWith = function (str) { return (this.match("^" + str) == str) }
              
              String.prototype.endsWith = function (str) { return (this.match(str + "$") == str) }
              

              页面功能(需要jQuery(几乎没有)):

              $("[id*='btnSaveForm']").click(function () {
                  if (!stringEndsWithValidExtension($("[id*='fileUploader']").val(), [".png", ".jpeg", ".jpg", ".bmp"], false)) {
                      alert("Photo only allows file types of PNG, JPG and BMP.");
                      return false;
                  }
                  return true;
              });
              

              【讨论】:

                【解决方案14】:

                [打字稿]

                uploadFileAcceptFormats: string[] = ['image/jpeg', 'image/gif', 'image/png', 'image/svg+xml'];
                
                // if you find the element type in the allowed types array, then read the file
                isAccepted = this.uploadFileAcceptFormats.find(val => {
                    return val === uploadedFileType;
                });
                

                【讨论】:

                  【解决方案15】:

                  在jquery中是这样处理的

                  $("#artifact_form").submit(function(){
                      return ["jpg", "jpeg", "bmp", "gif", "png"].includes(/[^.]+$/.exec($("#artifact_file_name").val())[0])
                    });
                  

                  【讨论】:

                    【解决方案16】:

                    当您要验证浏览按钮和文件扩展名时,请使用以下代码:

                    function fileValidate(){ 
                    var docVal=document.forms[0].fileUploaded.value;
                    var extension = docVal.substring(docVal.lastIndexOf(".")+1,docVal.length);
                    if(extension.toLowerCase() != 'pdf')
                    alert("Please enter file  in .pdf extension ");
                    
                    return false;
                    }
                    

                    【讨论】:

                    • 当你想验证浏览按钮和文件扩展名时,使用这个代码。
                    【解决方案17】:

                    我们可以在提交时检查它,或者我们可以对该控件进行更改事件

                    var fileInput = document.getElementById('file');
                        var filePath = fileInput.value;
                        var allowedExtensions = /(\.jpeg|\.JPEG|\.gif|\.GIF|\.png|\.PNG)$/;
                        if (filePath != "" && !allowedExtensions.exec(filePath)) {
                        alert('Invalid file extention pleasse select another file');
                        fileInput.value = '';
                        return false;
                        }
                    

                    【讨论】:

                      【解决方案18】:

                      使用数组

                      将所有文件扩展名/mimeType 添加到 validExtensions 数组中

                      const validExtensions = ["image/jpg", "image/jpeg", "image/png", "image/gif"];
                      const isValidExtension = validExtensions.indexOf(file.mimetype) > -1;
                      console.log(isValidExtension);
                      

                      【讨论】:

                        【解决方案19】:
                        <script type="text/javascript">
                        
                                function file_upload() {
                                    var imgpath = document.getElementById("<%=FileUpload1.ClientID %>").value;
                                    if (imgpath == "") {
                                        alert("Upload your Photo...");
                                        document.file.word.focus();
                                        return false;
                                    }
                                    else {
                                        // code to get File Extension..
                        
                                        var arr1 = new Array;
                                        arr1 = imgpath.split("\\");
                                        var len = arr1.length;
                                        var img1 = arr1[len - 1];
                                        var filext = img1.substring(img1.lastIndexOf(".") + 1);
                                        // Checking Extension
                                        if (filext == "bmp" || filext == "gif" || filext == "png" || filext == "jpg" || filext == "jpeg" ) {
                                            alert("Successfully Uploaded...")
                                            return false;
                                        }
                                        else {
                                            alert("Upload Photo with Extension ' bmp , gif, png , jpg , jpeg '");
                                            document.form.word.focus();
                                            return false;
                                        }
                                    }
                                }
                        
                                function Doc_upload() {
                                    var imgpath = document.getElementById("<%=FileUpload2.ClientID %>").value;
                                    if (imgpath == "") {
                                        alert("Upload Agreement...");
                                        document.file.word.focus();
                                        return false;
                                    }
                                    else {
                                        // code to get File Extension..
                        
                                        var arr1 = new Array;
                                        arr1 = imgpath.split("\\");
                                        var len = arr1.length;
                                        var img1 = arr1[len - 1];
                                        var filext = img1.substring(img1.lastIndexOf(".") + 1);
                                        // Checking Extension
                                        if (filext == "txt" || filext == "pdf" || filext == "doc") {
                                            alert("Successfully Uploaded...")
                                            return false;
                                        }
                                        else {
                                            alert("Upload File with Extension ' txt , pdf , doc '");
                                            document.form.word.focus();
                                            return false;
                                        }
                                    }
                                }
                        </script>
                        

                        【讨论】:

                        • 如果你写下你的答案的简短描述会更好。
                        【解决方案20】:

                        var _validFileExtensions = [".jpg", ".jpeg", ".bmp", ".gif", ".png"];    
                        function ValidateSingleInput(oInput) {
                            if (oInput.type == "file") {
                                var sFileName = oInput.value;
                                 if (sFileName.length > 0) {
                                    var blnValid = false;
                                    for (var j = 0; j < _validFileExtensions.length; j++) {
                                        var sCurExtension = _validFileExtensions[j];
                                        if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) {
                                            blnValid = true;
                                            break;
                                        }
                                    }
                                     
                                    if (!blnValid) {
                                        alert("Sorry, " + sFileName + " is invalid, allowed extensions are: " + _validFileExtensions.join(", "));
                                        oInput.value = "";
                                        return false;
                                    }
                                }
                            }
                            return true;
                        }
                        File 1: <input type="file" name="file1" onchange="ValidateSingleInput(this);" /><br />
                        File 2: <input type="file" name="file2" onchange="ValidateSingleInput(this);" /><br />
                        File 3: <input type="file" name="file3" onchange="ValidateSingleInput(this);" /><br />

                        【讨论】:

                          【解决方案21】:

                          您可以创建一个包含所需文件类型的数组,并在 jQuery 中使用 $.inArray() 来检查文件类型是否存在于数组中。

                          var imageType = ['jpeg', 'jpg', 'png', 'gif', 'bmp'];  
                          
                          // Given that file is a file object and file.type is string 
                          // like "image/jpeg", "image/png", or "image/gif" and so on...
                          
                          if (-1 == $.inArray(file.type.split('/')[1], imageType)) {
                            console.log('Not an image type');
                          }
                          

                          【讨论】:

                            【解决方案22】:

                            这是我认为的最佳解决方案,比其他解决方案要短得多:

                            function OnSelect(e) {
                                var acceptedFiles = [".jpg", ".jpeg", ".png", ".gif"];
                                var isAcceptedImageFormat = ($.inArray(e.files[0].extension, acceptedFiles)) != -1;
                            
                                if (!isAcceptedImageFormat) {
                                    $('#warningMessage').show();
                                }
                                else {
                                    $('#warningMessage').hide();
                                }
                            }
                            

                            在这种情况下,该函数是从具有此设置的 Kendo Upload 控件调用的:

                            .Events(e =&gt; e.Select("OnSelect")).

                            【讨论】:

                              猜你喜欢
                              • 2021-03-09
                              • 2014-11-06
                              • 2015-06-29
                              • 2012-01-02
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2018-11-26
                              相关资源
                              最近更新 更多