Validation of file extension before uploading file
JavascriptJqueryValidationFile UploadJavascript 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"))
.