104 votes

Comment le type MIME d'un fichier téléchargé est-il déterminé par le navigateur ?

J'ai une application web où l'utilisateur doit uploader un fichier .zip. Du côté serveur, je vérifie le type MIME du fichier uploadé pour m'assurer qu'il s'agit de application/x-zip-compressed ou application/zip.

Cela a fonctionné correctement pour moi sur Firefox et IE. Cependant, lorsqu'un collègue l'a testé, cela a échoué pour lui sur Firefox (le type MIME envoyé était quelque chose comme "application/octet-stream") mais a fonctionné sur Internet Explorer. Nos configurations semblent être identiques : IE8, FF 3.5.1 avec tous les modules complémentaires désactivés, Windows XP SP3, WinRAR installé comme gestionnaire de fichiers .zip natif (je ne suis pas sûr que cela soit pertinent).

Ma question est donc : Comment le navigateur détermine-t-il quel type MIME envoyer?

Veuillez noter : Je sais que le type MIME est envoyé par le navigateur et, par conséquent, peu fiable. Je le vérifie simplement comme une commodité - principalement pour afficher un message d'erreur plus convivial que ceux que vous obtenez en essayant d'ouvrir un fichier non-zip en tant que fichier zip, et pour éviter le chargement des bibliothèques de fichiers zip (presque certainement lourdes).

102voto

Stijn Points 6427

Chrome

Chrome (version 38 au moment de l'écriture) a 3 façons de déterminer le type MIME et le fait dans un certain ordre. L'extrait ci-dessous provient du fichier src/net/base/mime_util.cc, méthode MimeUtil::GetMimeTypeFromExtensionHelper.

// Nous implémentons le même algorithme que Mozilla pour faire correspondre une extension de fichier à
// un type MIME. C'est-à-dire, nous vérifions d'abord une liste codée en dur (qui ne peut pas être
// modifiée), et ensuite, si ce n'est pas trouvé là, nous faisons appel au registre système.
// Enfin, nous parcourons une deuxième liste codée en dur pour capturer les types que nous pouvons
// déduire mais que nous voulons également autoriser au système d'exploitation d'écraser.

Les listes codées en dur se trouvent un peu plus haut dans le fichier : https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170 (kPrimaryMappings et kSecondaryMappings).

Un exemple : lorsque vous téléchargez un fichier CSV à partir d'un système Windows avec Microsoft Excel installé, Chrome le rapportera comme application/vnd.ms-excel. Cela est dû au fait que .csv n'est pas spécifié dans la première liste codée en dur, et le navigateur se rabat alors sur le registre système. HKEY_CLASSES_ROOT\.csv a une valeur nommée Content Type qui est définie sur application/vnd.ms-excel.

Internet Explorer

Reprenant le même exemple, le navigateur rapportera application/vnd.ms-excel. Je pense qu'il est raisonnable de supposer qu'Internet Explorer (version 11 au moment de l'écriture) utilise le registre. Il est possible qu'il fasse également usage d'une liste codée en dur comme Chrome et Firefox, mais sa nature en source fermée rend difficile la vérification.

Firefox

Comme indiqué dans le code de Chrome, Firefox (version 32 au moment de l'écriture) fonctionne de manière similaire. Extrait du fichier uriloader\exthandler\nsExternalHelperAppService.cpp, méthode nsExternalHelperAppService::GetTypeFromExtension

// OK. Nous voulons essayer les sources d'information de type MIME suivantes, dans cet ordre :
// 1. tableau defaultMimeEntries
// 2. Préférences définies par l'utilisateur (gérées par le service de gestionnaire)
// 3. Information fournie par le système d'exploitation
// 4. notre tableau "extras"
// 5. Information provenant des plugins
// 6. La catégorie "ext-to-type-mapping"

Les listes codées en dur se trouvent plus haut dans le fichier, quelque part près de la ligne 441. Vous cherchez defaultMimeEntries et extraMimeEntries.

Avec mon profil actuel, le navigateur rapportera text/csv car il y a une entrée pour cela dans mimeTypes.rdf (élément 2 dans la liste ci-dessus). Avec un profile fraichement créé, qui ne contient pas cette entrée, le navigateur rapportera application/vnd.ms-excel (élément 3 dans la liste).

Résumé

Les listes codées en dur dans les navigateurs sont assez limitées. Souvent, le type MIME envoyé par le navigateur sera celui rapporté par le système d'exploitation. Et c'est exactement pourquoi, comme indiqué dans la question, le type MIME rapporté par le navigateur est peu fiable.

12voto

Kumar Points 2152

Kip, j'ai passé du temps à lire les RFC, la MSDN et la MDN. Voici ce que j'ai pu comprendre. Lorsqu'un navigateur rencontre un fichier à téléverser, il regarde le premier tampon de données qu'il reçoit puis effectue un test dessus. Ces tests tentent de déterminer si le fichier est un type mime connu ou non, et si le type mime est connu, il le teste simplement plus en détail pour déterminer quel type mime connu il est et agir en conséquence. Je pense qu'IE essaie de faire cela en premier lieu plutôt que de simplement déterminer le type de fichier à partir de l'extension. Cette page explique cela pour IE http://msdn.microsoft.com/en-us/library/ms775147%28v=vs.85%29.aspx. Pour Firefox, ce que j'ai pu comprendre, c'est qu'il essaie de lire les informations du fichier à partir du système de fichiers ou de l'entrée du répertoire, puis détermine le type de fichier. Voici un lien pour FF https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIFile. J'aimerais toujours avoir des informations plus autoritatives sur ce sujet.

8voto

Michael McCloskey Points 1765

Ceci est probablement dépendant du système d'exploitation et éventuellement du navigateur, mais sous Windows, le type MIME pour une extension de fichier donnée peut être trouvé en regardant dans le registre sous HKCR :

Par exemple :

HKEY_CLASSES_ROOT.zip - ContentType

Pour passer du type MIME à l'extension de fichier, vous pouvez regarder les clés sous

HKEY_CLASSES_ROOT\Mime\Database\Content Type

Pour obtenir l'extension par défaut pour un type MIME particulier.

6voto

johndodo Points 2975

Alors que ce n'est pas une réponse à votre question, cela résout le problème que vous essayez de résoudre. À chacun sa propre expérience.

Comme vous l'avez écrit, le type MIME n'est pas fiable car chaque navigateur a sa manière de le déterminer. Cependant, les navigateurs envoient le nom original (y compris l'extension) du fichier. Ainsi, la meilleure façon de résoudre le problème est d'inspecter l'extension du fichier au lieu du type MIME.

Si vous avez toujours besoin du type MIME, vous pouvez utiliser votre propre fichier mime.types d'apache pour le déterminer côté serveur.

0voto

Seul Shahkee Points 36

Je suis d'accord avec johndodo, il y a tellement de variables qui rendent les types MIME envoyés par les navigateurs peu fiables. Je exclurais les sous-types qui sont reçus et me concentrerais uniquement sur le type comme 'application'. Si votre application est basée sur PHP, vous pouvez facilement le faire en utilisant la fonction explode(). De plus, vérifiez juste l'extension du fichier pour vous assurer qu'il s'agit bien de .zip ou de toute autre compression que vous recherchez!

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