web-dev-qa-db-fra.com

Limiter le format de fichier lorsque vous utilisez <input type = "file">?

J'aimerais limiter le type de fichier pouvant être choisi dans le sélecteur de fichier du système d'exploitation natif lorsque l'utilisateur clique sur le bouton Parcourir de l'élément <input type="file"> en HTML. J'ai l'impression que c'est impossible, mais j'aimerais savoir s'il y a est une solution. Je voudrais rester uniquement au format HTML et JavaScript; pas de flash s'il vous plaît.

561
Bojangles

Strictement parlant, la réponse est non . Le développeur ne peut empêcher l'utilisateur de choisir des fichiers de n'importe quel type ou extension dans la boîte de dialogue de sélection de fichier du système d'exploitation natif.

Mais encore, l’attribut accepter de <input type = "file"> peut aider à fournir un filtre dans le la boîte de dialogue de sélection de fichier du système d'exploitation. Par exemple,

<!-- (IE 10+, Edge, Chrome, Firefox 42+) -->
<input type="file" accept=".xls,.xlsx" />

devrait fournir un moyen de filtrer les fichiers autres que .xls ou .xlsx. Bien que l'élément MDN de input ait toujours dit qu'il le supportait, à ma grande surprise, cela ne fonctionnait pas dans Firefox jusqu'à la version 42. Cela fonctionne dans IE 10+, Edge et Chrome.

Donc, pour supporter Firefox de plus de 42 ans avec IE 10+, Edge, Chrome et Opera, je suppose qu'il est préférable d'utiliser une liste de types MIME séparés par des virgules:

<!-- (IE 10+, Edge, Chrome, Firefox) -->
<input type="file"
 accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-Excel" /> 

[ Comportement du bord : la liste déroulante Filtre de type de fichier affiche les types de fichier mentionnés ici, mais n'est pas celle par défaut dans la liste déroulante. Le filtre par défaut est All files (*).]

Vous pouvez également utiliser des astérisques dans les types MIME. Par exemple:

<input type="file" accept="image/*" /> <!-- all image types --> 
<input type="file" accept="audio/*" /> <!-- all audio types --> 
<input type="file" accept="video/*" /> <!-- all video types --> 

W3C recommande Les auteurs doivent spécifier les types MIME et les extensions correspondantes dans l'attribut accept. Ainsi, la meilleure approche est la suivante:

<!-- Right approach: Use both file extensions and corresponding MIME-types. -->
<!-- (IE 10+, Edge, Chrome, Firefox) -->
<input type="file"
 accept=".xls,.xlsx, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-Excel" /> 

JSFiddle de la même: ici .

Référence: Liste de types MIME

IMPORTANT: L'utilisation de l'attribut accept ne permet de filtrer que les fichiers de types présentant un intérêt. Les navigateurs permettent toujours aux utilisateurs de choisir des fichiers de tout type. Des vérifications supplémentaires (côté client) doivent être effectuées (à l'aide de JavaScript, une méthode serait this ), et définitivement les types de fichiers DOIVENT être vérifié sur le serveur , en utilisant une combinaison de type MIME utilisant à la fois l'extension de fichier et sa signature binaire ( ASP.NET , PHP , Ruby , Java ). Vous pouvez également vous référer à ceux-citableaux pour les types de fichiers et leurs nombres magiques , afin d'effectuer une vérification plus robuste côté serveur.

Voici troisbienlit sur les téléchargements de fichiers et la sécurité.

EDIT: Peut-être que la vérification du type de fichier utilisant sa signature binaire peut également être effectuée côté client à l'aide de JavaScript (plutôt que simplement en regardant l'extension) à l'aide de HTML5 L'API de fichier, mais néanmoins, le fichier doit être vérifié sur le serveur, car un utilisateur malveillant pourra toujours télécharger des fichiers en créant une requête HTTP personnalisée.

930
Sachin Joseph

Il y a l'attribut accept pour la balise d'entrée. Cependant, ce n'est en aucun cas fiable. Les navigateurs la traitent probablement comme une "suggestion", ce qui signifie que l'utilisateur, en fonction du gestionnaire de fichiers également, aura une présélection qui affiche uniquement les types souhaités. Ils peuvent toujours choisir "tous les fichiers" et télécharger le fichier de leur choix.

Par exemple:

<form>
    <input type="file" name="pic" id="pic" accept="image/gif, image/jpeg" />
</form>

En savoir plus dans le spécification HTML5

N'oubliez pas qu'il ne doit être utilisé que comme une "aide" permettant à l'utilisateur de trouver les bons fichiers. Chaque utilisateur peut envoyer toute demande qu'il souhaite sur votre serveur. Vous devez toujours tout valider côté serveur.

Donc, la réponse est: non vous ne pouvez pas restreindre , mais vous pouvez définir une présélection mais vous ne pouvez pas compter dessus.

Alternativement ou en complément, vous pouvez faire quelque chose de similaire en vérifiant le nom de fichier (valeur du champ de saisie) avec JavaScript, mais cela n'a aucun sens car cela ne fournit aucune protection et ne facilite pas non plus la sélection de l'utilisateur. Cela incite potentiellement seulement un webmaster à penser qu'il est protégé et ouvre une faille de sécurité. Cela peut être un problème pour les utilisateurs qui ont des extensions de fichiers alternatives (par exemple, jpeg au lieu de jpg), des majuscules ou aucune extension de fichier (comme c'est le cas sur les systèmes Linux).

190
The Surrican

Vous pouvez utiliser l'événement change pour contrôler ce que l'utilisateur sélectionne et lui indiquer à ce stade que le fichier n'est pas acceptable. Cela ne limite pas la liste réelle des fichiers affichés, mais c’est le plus proche que vous puissiez faire côté client, en plus de l’attribut mal pris en charge accept.

var file = document.getElementById('someId');

file.onchange = function(e) {
  var ext = this.value.match(/\.([^\.]+)$/)[1];
  switch (ext) {
    case 'jpg':
    case 'bmp':
    case 'png':
    case 'tif':
      alert('Allowed');
      break;
    default:
      alert('Not allowed');
      this.value = '';
  }
};
<input type="file" id="someId" />

JSFiddle

89
Gabriele Petrioli

Oui, tu as raison. C'est impossible avec HTML. L'utilisateur pourra choisir le fichier qu'il veut.

Vous pouvez écrire un morceau de code JavaScript pour éviter de soumettre un fichier en fonction de son extension. Mais gardez à l'esprit que cela n'empêchera en aucun cas un utilisateur malveillant de soumettre un fichier qu'il/elle veut vraiment.

Quelque chose comme:

function beforeSubmit()
{
    var fname = document.getElementById("ifile").value;
    // check if fname has the desired extension
    if (fname hasDesiredExtension) {
        return true;
    } else {
        return false;
    }
}

Code HTML:

<form method="post" onsubmit="return beforeSubmit();">
    <input type="file" id="ifile" name="ifile"/>
</form>
45
Pablo Santa Cruz

Techniquement, vous pouvez spécifier attribut accept (alternative dans html5 ) sur l'élément input, mais ce n'est pas pris en charge correctement.

18
zzzzBov

Utiliser la balise input avec l'attribut accept

<input type="file" name="my-image" id="image" accept="image/gif, image/jpeg, image/png" />

Cliquez ici pour le dernier tableau de compatibilité de navigateur

Démo en direct ici

Pour sélectionner uniquement les fichiers d’image, vous pouvez utiliser ce accept="image/*"

<input type="file" name="my-image" id="image" accept="image/*" />

Démo en direct ici

Only gif, jpg and png will be shown, screen grab from Chrome version 44 Seuls les formats gif, jpg et png seront affichés, capture d'écran de Chrome version 44

9
kiranvj

Je sais que c'est un peu tard.

function Validatebodypanelbumper(theForm)
{
   var regexp;
   var extension =     theForm.FileUpload.value.substr(theForm.FileUpload1.value.lastIndexOf('.'));
   if ((extension.toLowerCase() != ".gif") &&
       (extension.toLowerCase() != ".jpg") &&
       (extension != ""))
   {
      alert("The \"FileUpload\" field contains an unapproved filename.");
      theForm.FileUpload1.focus();
      return false;
   }
   return true;
}
8
bpross

Vous pouvez réellement le faire avec javascript, mais souvenez-vous que js est le côté client. Vous devez donc "avertir les utilisateurs" du type de fichiers qu'ils peuvent télécharger, si vous souhaitez ÉVITER (restreindre ou limiter, comme vous l'avez dit) certains types de fichiers que vous DEVEZ faites-le côté serveur.

Regardez ce tutoriel de base si vous souhaitez vous initier à la validation côté serveur. Pour la visite complète du tutoriel cette page .

Bonne chance!

5
Trufa

Comme mentionné dans les réponses précédentes, nous ne pouvons pas empêcher l'utilisateur de sélectionner des fichiers uniquement pour des formats de fichier donnés. Mais il est très pratique d'utiliser l'attribut accept sur l'attribut de fichier en HTML.

En ce qui concerne la validation, nous devons le faire côté serveur. Nous pouvons également le faire côté client dans js mais ce n’est pas une solution à toute épreuve. Nous devons valider côté serveur.

Pour ces besoins, je préfère vraiment struts2 Java framework de développement d’applications Web. Avec sa fonctionnalité intégrée de téléchargement de fichiers, le téléchargement de fichiers vers des applications Web basées sur struts2 est un jeu d'enfant. Il suffit de mentionner les formats de fichiers que nous aimerions accepter dans notre application et tout le reste est pris en charge par le noyau du cadre lui-même. Vous pouvez le vérifier sur le site officiel de struts.

2
svg