[javascript] Validation of file extension before uploading file

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.

This question is related to javascript jquery validation file-upload

The answer is


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

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

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

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.


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

So, you can try something like this:

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

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

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

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


Another nowadays example via Array.prototype.some().

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


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!


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

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


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")).


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

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

try this (Works for me)

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


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>

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

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

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

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


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to validation

Rails 2.3.4 Persisting Model on Validation Failure Input type number "only numeric value" validation How can I manually set an Angular form field as invalid? Laravel Password & Password_Confirmation Validation Reactjs - Form input validation Get all validation errors from Angular 2 FormGroup Min / Max Validator in Angular 2 Final How to validate white spaces/empty spaces? [Angular 2] How to Validate on Max File Size in Laravel? WebForms UnobtrusiveValidationMode requires a ScriptResourceMapping for jquery

Examples related to file-upload

bootstrap 4 file input doesn't show the file name How to post a file from a form with Axios File Upload In Angular? How to set the max size of upload file The request was rejected because no multipart boundary was found in springboot Send multipart/form-data files with angular using $http File upload from <input type="file"> How to upload files in asp.net core? REST API - file (ie images) processing - best practices Angular - POST uploaded file