Validation of file extension before uploading file

JavascriptJqueryValidationFile Upload

Javascript Problem Overview


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.

I am using Javascript and jQuery in client side.

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

Javascript Solutions


Solution 1 - Javascript

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

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.

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

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.

Solution 2 - Javascript

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 upload is the id of a file input):

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

Or as a jQuery plugin:

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

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!

Solution 3 - Javascript

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

Solution 4 - Javascript

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

Solution 5 - Javascript

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

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

Solution 6 - Javascript

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

Solution 7 - Javascript

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>

Solution 8 - Javascript

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.

$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 ending in .gif, .jpg, .jpeg, .tiff or .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:

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.

Solution 9 - Javascript

Better to try with mimetype than checking extension. Because, sometimes files can be exist without it and those are working very well in linux or unix systems.

So, you can try something like this:

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

or

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

Solution 10 - Javascript

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>

     

Solution 11 - Javascript

You can use the accept attribute available for input file types. Checkout MDN documentation

Solution 12 - Javascript

Another nowadays example via 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'));

Solution 13 - Javascript

Here is a more reusable way, assuming you use jQuery

Library function (does not require 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) }

Page function (requires jQuery (barely)):

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

Solution 14 - Javascript

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

Solution 15 - Javascript

When you want to validate browse button and file extension, use this code:

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

Solution 16 - Javascript

This is how it is done in jquery

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

Solution 17 - Javascript

we can check it on submit or we can make change event of that control

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

Solution 18 - Javascript

using Array

> Add all of your file-extensions/mimeType in validExtensions Array

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

Solution 19 - Javascript

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

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

Solution 21 - Javascript

You can create an array that includes the filetype that is needed and use $.inArray() in jQuery to check if filetype exist in array.

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

Solution 22 - Javascript

This is the best solution in my opinion, which is by far much shorter than the other ones:

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

In this case, the function is called from a Kendo Upload control with this setting:

.Events(e => e.Select("OnSelect")).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser405398View Question on Stackoverflow
Solution 1 - JavascriptShadow Wizard Says No More WarView Answer on Stackoverflow
Solution 2 - JavascriptOrblingView Answer on Stackoverflow
Solution 3 - JavascriptAshish PathakView Answer on Stackoverflow
Solution 4 - JavascriptCedric IpkissView Answer on Stackoverflow
Solution 5 - JavascriptRouvenView Answer on Stackoverflow
Solution 6 - JavascriptRizwan GillView Answer on Stackoverflow
Solution 7 - Javascriptkamal.shalabeView Answer on Stackoverflow
Solution 8 - Javascriptuser3789031View Answer on Stackoverflow
Solution 9 - JavascriptDananjayaView Answer on Stackoverflow
Solution 10 - JavascriptAlpha 1View Answer on Stackoverflow
Solution 11 - JavascriptAditibtpView Answer on Stackoverflow
Solution 12 - JavascriptPenny LiuView Answer on Stackoverflow
Solution 13 - JavascriptMicah B.View Answer on Stackoverflow
Solution 14 - JavascriptmkupiniakView Answer on Stackoverflow
Solution 15 - JavascriptAjay Kumar GuptaView Answer on Stackoverflow
Solution 16 - JavascriptJinja2DjangoView Answer on Stackoverflow
Solution 17 - JavascriptDivyesh JaniView Answer on Stackoverflow
Solution 18 - JavascriptNuman AhmedView Answer on Stackoverflow
Solution 19 - Javascriptuser3060112View Answer on Stackoverflow
Solution 20 - JavascriptfrancinView Answer on Stackoverflow
Solution 21 - JavascriptJohn RocaView Answer on Stackoverflow
Solution 22 - JavascriptAndrewView Answer on Stackoverflow