98 votes

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

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

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

Mise à jour : J'ai finalement abouti à une validation côté serveur qui lit les octets et rejette le téléchargement s'il ne s'agit pas d'une image.

2 votes

Vous utilisez Uploadify comme suggéré dans une de vos questions précédentes, n'est-ce pas ?

0 votes

Non, il s'arrête entre 50 et 96. J'ai essayé de nombreuses fois avec différentes entrées. Et j'étais également pressé de trouver une solution à ce moment-là. J'ai donc essayé une solution simple jquery.ProgressBar.js . Cela fonctionne, bien. ### Alors, est-ce que je peux valider avec uploadify !!!

0 votes

Ne pouvons-nous pas simplement utiliser l'attribut accept dans la balise input afin de nous assurer que l'utilisateur sélectionne le fichier du format spécifié ?

121voto

Shadow Wizard Points 38568

Il est possible de ne vérifier que 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 le 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>

Note, le code permettra à l'utilisateur d'envoyer sans choisir de fichier... si c'est nécessaire, supprimez la ligne if (sFileName.length > 0) { et le crochet de fermeture qui lui est 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 le JavaScript "brut" et le résultat final est le même.

Si vous avez plus de fichiers, ou si vous voulez déclencher la vérification lors du changement de fichier et pas seulement lors de la soumission du formulaire, utilisez ce code à la place :

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

0 votes

Je voudrais juste ajouter que l'utilisation de "onSubmit" au lieu de "onChange" est encombrante - surtout si l'option "multiple" est utilisée. Chaque fichier devrait être vérifié au fur et à mesure qu'il est sélectionné, et non lorsque le formulaire entier est affiché.

0 votes

@DevlshOne idée intéressante, je le mentionnerai également dans le post. Merci !

0 votes

Merci beaucoup pour ce code @Shadow Wizard, il m'a vraiment beaucoup aidé !

76voto

Orbling Points 13319

Aucune des réponses existantes ne semblait assez compacte pour la simplicité de la demande. Vérifier si un champ d'entrée de fichier donné a une extension provenant d'un ensemble peut être accompli 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ù upload est le id d'un fichier d'entrée) :

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 site .replace(/\./g, '\\.') est là pour échapper au point de l'expression rationnelle afin que les extensions de base puissent être passées sans que le point ne corresponde à aucun caractère.

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

10 votes

Sympathique. Notez que ces scripts sont sensibles à la casse. Pour résoudre ce problème, vous devez donner RexExp the "i" modifier, for example: return (new RegExp('(' + exts.join('|').replace(/\./g, '\\.') + ')$', "i")).test(fileName);

2 votes

Un peu difficile à lire, mais cela signifie ajouter , "i" après la fin de la chaîne regex ( )$' ). Cela ajoutera le support de n'importe quelle casse dans l'extension du nom de fichier (.jpg, .JPG, .Jpg, etc...)

0 votes

Merci, Tedd, ce serait mieux d'avoir une correspondance insensible à la casse.

9voto

Rizwan Gill Points 454

vérifier 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;
             }
    }

8voto

kamal.shalabe Points 41

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>

6voto

user3789031 Points 1

Si vous avez besoin de tester des urls distantes dans un champ de saisie, vous pouvez essayer de tester une simple expression rationnelle 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 va capturer tout ce qui fin du site en .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, l'image suivante échouerait à ce test bien qu'il s'agisse 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 elle vous permettra de faire environ 90 % du chemin.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X