Javascript 上传文件前验证文件扩展名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4234589/
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-23 11:30:58  来源:igfitidea点击:

Validation of file extension before uploading file

javascriptjqueryvalidationfile-upload

提问by Shadow Wizard is Ear For You

I am uploading images to a servlet. The validation whether the uploaded file is an image is done in server side only, by checking the magic numbers in the file header. Is there any way to validate the extensions in client side before submitting the form to servlet? As soon as I hit enter it starts uploading.

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

I am using Javascript and jQuery in client side.

我在客户端使用 Javascript 和 jQuery。

Update:I was finally ended up with server side validation which reads bytes & rejects the upload if it is not an image.

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

回答by Shadow Wizard is Ear For You

It's possible to check only the file extension, but user can easily rename virus.exe to virus.jpg and "pass" the validation.

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

For what it's worth, here is the code to check file extension and abort if does not meet one of the valid extensions: (choose invalid file and try to submit to see the alert in action)

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

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>

Note, the code will allow user to send without choosing file... if it's required, remove the line if (sFileName.length > 0) {and it's associate closing bracket. The code will validate any file input in the form, regardless of its name.

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

This can be done with jQuery in less lines, but I'm comfortable enough with "raw" JavaScript and the final result is the same.

这可以用更少的行使用 jQuery 来完成,但我对“原始”JavaScript 足够满意,最终结果是一样的。

In case you have more files, or want to trigger the check upon changing the file and not only in form submission, use such code instead:

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

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 />

This will show alert and reset the input in case of invalid file extension.

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

回答by Orbling

None of the existing answers seemed quite compact enough for the simplicity of the request. Checking if a given file input field has an extension from a set can be accomplished as follows:

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

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

So example usage might be (where uploadis the idof a file input):

因此,例如使用可能(这里uploadid一个文件输入的):

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

Or as a jQuery plugin:

或者作为 jQuery 插件:

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

Example usage:

用法示例:

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

The .replace(/\./g, '\\.')is there to escape the dot for the regexp so that basic extensions can be passed in without the dots matching any character.

.replace(/\./g, '\\.')有逃脱的正则表达式的点,使基础扩展可以在没有匹配任何字符的点进行传递。

There's no error checking on these to keep them short, presumably if you use them you'll make sure the input exists first and the extensions array is valid!

没有对这些进行错误检查以保持它们的简短,大概如果您使用它们,您将确保输入首先存在并且扩展数组有效!

回答by Ashish pathak

$(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');
        }
    });
});

回答by che-azeh

I came here because I was sure none of the answers here were quite...poetic:

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

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

回答by Rizwan Gill

check that if file is selected or not

检查是否选择了文件

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

check the file extension

检查文件扩展名

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

回答by kamal.shalabe

I like this example:

我喜欢这个例子:

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

回答by user3789031

If you're needing to test remote urls in an input field, you can try testing a simple regex with the types that you're interested in.

如果您需要在输入字段中测试远程 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;
}

This will capture anything endingin .gif, .jpg, .jpeg, .tiff or .png

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

I should note that some popular sites like Twitter append a size attribute to the end of their images. For instance, the following would fail this test even though it's a valid image type:

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

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

Because of that, this isn't a perfect solution. But it will get you to about 90% of the way.

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

回答by Ravi Kumar

try this (Works for me)

试试这个(对我有用)

  
  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>

     

回答by Rouven

Do you use the input type="file" to choose the uploadfiles? if so, why not use the accept attribute?

您是否使用 input type="file" 来选择上传文件?如果是这样,为什么不使用 accept 属性?

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

回答by mkupiniak

[TypeScript]

[打字稿]

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