Checking the file extension before downloading the file

I upload images to a servlet. Checking whether the downloaded file is an image is performed only on the server side, checking the magic numbers in the file header. Is there a way to test client-side extensions before submitting the form to the servlet? As soon as I hit it, it starts loading.

I use Javascript and jQuery on the client side.

Update: Finally, I ended up checking on the server side, which reads bytes and rejects the download if it is not an image.

+76
javascript jquery validation file-upload
Nov 20 '10 at 19:37
source share
18 answers

You can only check the file extension, but the user can easily rename virus.exe to the virus.jpg file and "pass" the check.

For what it's worth, here is the code to check the file extension and interrupt if it does not match one of the valid extensions: (select an invalid file and try sending to see a warning 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 that the code will allow the user to send without selecting a file ... if necessary, delete the line if (sFileName.length > 0) { and match the closing bracket. The code will check any input file in the form, regardless of its name.

This can be done using jQuery in fewer lines, but I'm comfortable with raw JavaScript, and the end result is the same.

If you have more files or want to run a check when a file changes, and not just in the form view, use this code:

 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 trigger a warning and reset the input if the file extension is invalid.

+105
Nov 21 '10 at 9:17
source share

None of the existing answers seemed compact enough for ease of request. Checking whether a given file input field can have an extension from a set can be performed as follows:

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

So an example could be (where upload is the id to enter the file):

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

Usage example:

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

.replace(/\./g, '\\.') , regex dots should be avoided so that base extensions can be passed without dots matching any character.

There is no error checking them to be short, presumably if you use them, you will make sure that the input exists first, and the array of extensions is valid!

+64
Jun 28 '13 at 1:38
source share
 $(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'); } }); }); 
+26
Mar 18 '15 at 6:43
source share

I came here because I was sure that none of the answers here was ... 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()"/> 
+14
Nov 22 '16 at 23:07
source share

check if the 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 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; } } 
+9
May 21 '13 at 11:11
source share

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> 
+8
Sep 29 '12 at 21:59
source share

If you need to check for remote URLs in the input field, you can try testing a simple regular expression with the types that interest you.

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

I should note that some popular sites like Twitter add a size attribute to the end of their images. For example, the following test would fail even if it is a valid image type:

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

Because of this, this is not an ideal solution. But it will bring you closer to 90% of the way.

+5
Jun 30 '14 at 4:59
source share

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> 
+4
Mar 25 '17 at 16:11
source share

Do you use input type = "file" to select uploaded files? if so, why not use the accept attribute?

 <input type="file" name="myImage" accept="image/x-png,image/gif,image/jpeg" /> 
+3
Sep 07 '18 at 14:21
source share

Here is a more reusable way, assuming you are using 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 (jQuery required (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; }); 
+1
Aug. 07 '12 at 18:59
source share

[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
Mar 29 '17 at 10:51 on
source share

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

+1
May 6 '17 at 7:26
source share
 <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> 
0
Dec 03 '13 at 5:48
source share

 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
Jul 24 '15 at 7:19
source share

You can create an array that contains the desired file type and use $ .inArray () in jQuery to check if the filetype file exists in the 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'); } 
0
Nov 20 '15 at 6:05
source share

If you want to check the 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 "); enableAll(); return false; } 
0
Apr 24 '19 at 7:13
source share

Here's how to do it in jQuery

 $("#artifact_form").submit(function(){ return ["jpg", "jpeg", "bmp", "gif", "png"].includes(/[^.]+$/.exec($("#artifact_file_name").val())[0]) }); 
0
Jul 13 '19 at 9:16
source share

This is the best solution, in my opinion, which is much shorter than others:

 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 the Kendo Upload control with this parameter:

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

-one
Mar 22 '17 at 20:40
source share



All Articles