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


90

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

我在客户端使用Javascript和jQuery。

更新: 我最终结束了服务器端验证,该验证读取字节,如果不是图像,则拒绝上传。


2
您正在按照上一个问题中的建议使用Uploadify,对吗?
BalusC

不,它停留在50-96之间。多次尝试各种输入。而且,当时我也急于寻求解决方案。因此,我尝试了简单jquery.ProgressBar.js。很好,很好。###因此,我可以使用uploadify进行验证!!!


我们不能只是为了确保用户选择指定格式的文件而在input标签中简单地使用accept属性吗?
AnonSar

Answers:


117

可以仅检查文件扩展名,但是用户可以轻松地将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 > 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”选项。每个文件都应选中时检查,而不是在发布整个表单时检查。
DevlshOne,2015年

@Devlsh一个有趣的主意,也会在帖子中提及。谢谢!
暗影巫师为您耳边

非常感谢@Shadow Wizard的这段代码,对我的帮助很大!
Anahit Ghazaryan

1
@garryman失败如何?这里的问题没有提到文件是必需的。如果您的文件是必填字段,则可以移动该行var blnValid = false;移到循环上方的arrInputs上方,然后在循环之后检查变量blnValid:如果为true,则让表单提交,否则显示警报提示该文件是必需的。
影子巫师为您服务

检查我下面的答案
Divyesh Jani

72

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

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

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

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, '\\.')来避开正则表达式的点,以便可以传递基本扩展名而使点不与任何字符匹配。

没有对它们的错误检查以使它们简短,大概是如果您使用它们,则将确保输入首先存在且extensions数组有效!


10
真好 请注意,这些脚本区分大小写。为了解决这个问题,你需要给RexExp the "i" modifier, for example: return (new RegExp('(' + exts.join('|').replace(/\./g, '\\.') + ')$', "i")).test(fileName);
Tedd汉森

2
有点难以理解,但这意味着, "i"在正则表达式字符串()$')的末尾添加。这将增加对文件扩展名(.jpg,.JPG,.Jpg等)中所有大小写的支持
Tedd Hansen 2016年

谢谢Tedd,最好使用不区分大小写的匹配。
Orbling

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

谢谢,非常简单和干净。
Th3_hide

如果按取消,它将触发警报。
PinoyStackOverflower

18

我来这里是因为我确信这里没有答案是很诗意的:

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()"/>


感谢在Angular中
所做的

对我来说效果很好,尽管应该在测试前从名称中删除任何尾随空格。+1
罗伯托

9

检查是否选择了文件

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

8

我喜欢这个例子:

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

7

您是否使用输入type =“ file”选择上载文件?如果是这样,为什么不使用accept属性?

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

这个!accept="image/*"在大多数情况下,这绝对是最明智的选择。
Alberto T.

6

如果您需要在输入字段中测试远程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%的目标。


4

试试这个(对我有用)

  
  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>

     


2

时下的另一个示例通过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'));


1

假设您使用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;
});

1

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



1

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

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

1
当您要验证浏览按钮和文件扩展名时,请使用此代码。
Ajay Kumar Gupta

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

3
如果对答案写上简短的描述,那会更好。
Roopendra

0

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


0

您可以创建一个包含所需文件类型的数组,并在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');
}

0

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

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

-1

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

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 => e.Select("OnSelect"))

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.