Validation de l'extension de fichier avant le téléchargement du fichier

90

Je télécharge des images sur un servlet. La validation si le fichier téléchargé est une image se fait uniquement côté serveur, en vérifiant les nombres magiques dans l'en-tête du fichier. Existe-t-il un moyen de valider les extensions côté client avant de soumettre le formulaire au servlet? Dès que j'appuie sur Entrée, le téléchargement commence.

J'utilise Javascript et jQuery côté client.

Mise à jour: je me suis finalement retrouvé avec une validation côté serveur qui lit les octets et rejette le téléchargement s'il ne s'agit pas d'une image.


la source
2
Vous utilisez Uploadify comme suggéré dans l'une de vos questions précédentes, n'est-ce pas?
BalusC
Non, ça s'arrête entre 50-96. Essayé plusieurs fois avec diverses entrées. Et j'étais aussi pressé de trouver une solution à l'époque. Alors, j'ai essayé de faire simple jquery.ProgressBar.js. Ça fonctionne bien. ### Alors, puis-je valider avec uploadify !!!
Ne pouvons-nous pas simplement utiliser l'attribut accept dans la balise d'entrée afin de nous assurer que l'utilisateur sélectionne le fichier au format spécifié?
AnonSar

Réponses:

117

Il est possible de vérifier uniquement l'extension du fichier, mais l'utilisateur peut facilement renommer virus.exe en virus.jpg et "passer" la validation.

Pour ce que ça vaut, voici le code pour vérifier l'extension du fichier et abandonner s'il ne correspond pas à l'une des extensions valides: (choisissez un fichier invalide et essayez de soumettre pour voir l'alerte en 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>

Notez que le code permettra à l'utilisateur d'envoyer sans choisir de fichier ... si nécessaire, supprimez la ligne if (sFileName.length > 0) {et son crochet fermant associé. Le code validera toute entrée de fichier dans le formulaire, quel que soit son nom.

Cela peut être fait avec jQuery en moins de lignes, mais je suis assez à l'aise avec JavaScript "brut" et le résultat final est le même.

Si vous avez plus de fichiers, ou souhaitez déclencher la vérification lors du changement de fichier et pas seulement lors de la soumission du formulaire, utilisez plutôt ce 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 />

Cela affichera une alerte et réinitialisera l'entrée en cas d'extension de fichier non valide.

Shadow Wizard est une oreille pour vous
la source
Je voudrais juste ajouter que l'utilisation de "onSubmit" au lieu de "onChange" est fastidieuse - surtout si l'option "multiple" est utilisée. Chaque fichier doit être vérifié tel qu'il est sélectionné, et non lorsque le formulaire entier est publié.
DevlshOne
@DevlshOne idée intéressante, mentionnera également cela dans le post. Merci!
Shadow Wizard est une oreille pour vous
Merci beaucoup pour ce code @Shadow Wizard, il m'a vraiment beaucoup aidé!
Anahit Ghazaryan
1
@garryman échoue comment? La question ici ne mentionne pas que le fichier est obligatoire. Si dans votre cas, le fichier est un champ obligatoire, vous pouvez déplacer la ligne var blnValid = false;au-dessus de la boucle sur arrInputs, puis après la boucle, vérifiez la variable blnValid: si true, laissez le formulaire soumettre, sinon affichez l'alerte que le fichier est requis.
Shadow Wizard est une oreille pour vous le
Vérifiez ma réponse ci-dessous
Divyesh Jani
73

Aucune des réponses existantes ne semblait assez compacte pour la simplicité de la demande. La vérification si un champ d'entrée de fichier donné a une extension à partir d'un ensemble peut être effectuée comme suit:

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

Ainsi, un exemple d'utilisation pourrait être (où uploadest l' identrée d'un fichier):

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

Ou en tant que plugin jQuery:

$.fn.hasExtension = function(exts) {
    return (new RegExp('(' + exts.join('|').replace(/\./g, '\\.') + ')$')).test($(this).val());
}

Exemple d'utilisation:

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

Le .replace(/\./g, '\\.')est là pour échapper au point de l'expression rationnelle afin que les extensions de base puissent être passées sans que les points ne correspondent à aucun caractère.

Il n'y a pas de vérification d'erreur sur ceux-ci pour les garder courts, probablement si vous les utilisez, vous vous assurerez d'abord que l'entrée existe et que le tableau d'extensions est valide!

Orbling
la source
10
Agréable. Notez que ces scripts sont sensibles à la casse. Pour résoudre ce problème, vous devez donnerRexExp the "i" modifier, for example: return (new RegExp('(' + exts.join('|').replace(/\./g, '\\.') + ')$', "i")).test(fileName);
Tedd Hansen
2
Un peu difficile à lire, mais cela signifie ajouter , "i"après la fin de la chaîne de regex ( )$'). Cela ajoutera la prise en charge de toute casse dans l'extension de nom de fichier (.jpg, .JPG, .Jpg, etc ...)
Tedd Hansen
Merci, Tedd, serait préférable d'avoir une correspondance insensible à la casse.
Orbling
39
$(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');
        }
    });
});
Ashish Pathak
la source
1
Merci, très simple et propre.
Jeu3_hide
si vous appuyez sur Annuler, cela déclenchera une alerte.
PinoyStackOverflower
18

Je suis venu ici parce que j'étais sûr qu'aucune des réponses ici n'était tout à fait ... poétique:

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

Cédric Ipkiss
la source
Merci, cela fonctionne en angulaire avec peu de modifications, merci
skydev
a bien fonctionné pour moi, bien qu'il faille supprimer les espaces de fin du nom avant de tester. +1
Roberto
9

vérifier que si le fichier est sélectionné ou non

       if (document.myform.elements["filefield"].value == "")
          {
             alert("You forgot to attach file!");
             document.myform.elements["filefield"].focus();
             return false;  
         }

vérifier l'extension du fichier

  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;
             }
    }
Rizwan Gill
la source
8

J'aime cet exemple:

<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>
kamal.shalabe
la source
7

Utilisez-vous le type d'entrée = "fichier" pour choisir les fichiers de téléchargement? si tel est le cas, pourquoi ne pas utiliser l'attribut accept?

<input type="file" name="myImage" accept="image/x-png,image/gif,image/jpeg" />
Rouven
la source
Ce! accept="image/*"c'est certainement le choix le plus intelligent dans la plupart des cas.
Alberto T.
6

Si vous avez besoin de tester des URL distantes dans un champ de saisie, vous pouvez essayer de tester une simple regex avec les types qui vous intéressent.

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

Cela capturera tout ce qui se termine par .gif, .jpg, .jpeg, .tiff ou .png

Je dois noter que certains sites populaires comme Twitter ajoutent un attribut de taille à la fin de leurs images. Par exemple, ce qui suit échouerait ce test même s'il s'agit d'un type d'image valide:

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

Pour cette raison, ce n'est pas une solution parfaite. Mais cela vous mènera à environ 90% du chemin.

user3789031
la source
4

essayez ceci (fonctionne pour moi)

  
  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>

     

AlphaOne
la source
2

Un autre exemple de nos jours 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'));

Penny Liu
la source
1

Voici une manière plus réutilisable, en supposant que vous utilisez jQuery

Fonction de bibliothèque (ne nécessite pas 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) }

Fonction de page (nécessite jQuery (à peine)):

$("[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;
});
Micah B.
la source
1

[Manuscrit]

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;
});
mkupiniak
la source
1

Vous pouvez utiliser l' acceptattribut disponible pour les types de fichiers d'entrée. Consulter la documentation MDN

Aditibtp
la source
2
Avec cela, vous pouvez toujours sélectionner d'autres types de fichiers
César León
@ CésarLeón Oui. L'utilisateur a la possibilité de sélectionner tous les fichiers. Si vous souhaitez restreindre cela également, vous devez effectuer une validation manuelle. Vérifiez les autres réponses.
Madura Pradeep
1

Voici comment cela se fait dans jquery

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

Lorsque vous souhaitez valider le bouton Parcourir et l'extension de fichier, utilisez ce 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;
}
Ajay Kumar Gupta
la source
1
lorsque vous souhaitez valider le bouton Parcourir et l'extension de fichier, utilisez ce code.
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>
user3060112
la source
3
Il vaudrait mieux que vous écriviez une brève description de votre réponse.
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 />

francin
la source
0

Vous pouvez créer un tableau qui inclut le type de fichier nécessaire et utiliser $ .inArray () dans jQuery pour vérifier si le type de fichier existe dans le tableau.

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');
}
John Roca
la source
0

nous pouvons le vérifier lors de la soumission ou nous pouvons modifier l'événement de ce contrôle

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;
    }
Divyesh Jani
la source
0

Je pense qu'il vaut mieux essayer avec mimetype que de vérifier l'extension. Parce que, parfois, des fichiers peuvent exister sans lui et ils fonctionnent très bien dans les systèmes Linux et Unix.

Donc, vous pouvez essayer quelque chose comme ceci:

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

C'est la meilleure solution à mon avis, qui est de loin beaucoup plus courte que les autres:

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

Dans ce cas, la fonction est appelée à partir d'un contrôle Kendo Upload avec ce paramètre:

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

Andrew
la source