J'ai une application Web dans laquelle l'utilisateur doit télécharger un fichier .zip. Du côté serveur, je vérifie le type mime du fichier téléchargé, pour m'assurer qu'il estapplication/x-zip-compressed
ou application/zip
.
Cela a bien fonctionné pour moi sur Firefox et IE. Cependant, lorsqu'un collègue l'a testé, il 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 désactivés, Win XP SP3, WinRAR installé en tant que gestionnaire de fichiers .zip natif (je ne sais pas si c'est pertinent).
Ma question est donc: comment le navigateur détermine-t-il quel type de mime envoyer?
Veuillez noter: je sais que le type mime est envoyé par le navigateur et donc peu fiable. Je le vérifie simplement par commodité - principalement pour donner 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 de charger les bibliothèques de fichiers zip (vraisemblablement lourdes).
input/@formenctype
ouform/@enctype
attributsRéponses:
Chrome
Chrome (version 38 au moment de la rédaction) dispose de 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éthodeMimeUtil::GetMimeTypeFromExtensionHelper
.Les listes codées en dur viennent un peu plus tôt dans le fichier: https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170 (
kPrimaryMappings
etkSecondaryMappings
).Un exemple: lors du téléchargement d'un fichier CSV à partir d'un système Windows avec Microsoft Excel installé, Chrome le signalera comme
application/vnd.ms-excel
. C'est parce que.csv
n'est pas spécifié dans la première liste codée en dur, de sorte que le navigateur revient au registre système.HKEY_CLASSES_ROOT\.csv
a une valeur nomméeContent Type
définie surapplication/vnd.ms-excel
.Internet Explorer
Toujours en utilisant le même exemple, le navigateur fera un rapport
application/vnd.ms-excel
. Je pense qu'il est raisonnable de supposer Internet Explorer (version 11 au moment de la rédaction) utilise le registre. Peut-être qu'il utilise également une liste codée en dur comme Chrome et Firefox, mais sa nature de source fermée le rend difficile à vérifier.Firefox
Comme indiqué dans le code Chrome, Firefox (version 32 au moment de la rédaction) fonctionne de la même manière. Extrait de fichier
uriloader\exthandler\nsExternalHelperAppService.cpp
, méthodensExternalHelperAppService::GetTypeFromExtension
Les listes codées en dur viennent plus tôt dans le fichier, quelque part près de la ligne 441. Vous recherchez
defaultMimeEntries
etextraMimeEntries
.Avec mon profil actuel, le navigateur fera un rapport
text/csv
car il y a une entrée pour lui dansmimeTypes.rdf
(élément 2 dans la liste ci-dessus). Avec un nouveau profil, qui n'a pas cette entrée, le navigateur signaleraapplication/vnd.ms-excel
(élément 3 dans la liste).Sommaire
Les listes codées en dur dans les navigateurs sont assez limitées. Souvent, le type MIME envoyé par le navigateur sera celui signalé par le système d'exploitation. Et c'est exactement pourquoi, comme indiqué dans la question, le type MIME indiqué par le navigateur n'est pas fiable.
la source
Kip, j'ai passé du temps à lire les RFC, MSDN et MDN. Voici ce que j'ai pu comprendre. Lorsqu'un navigateur rencontre un fichier à télécharger, il examine le premier tampon de données qu'il reçoit, puis exécute un test dessus. Ces tests tentent de déterminer si le fichier est d'un type mime connu ou non, et s'il s'agit d'un type mime connu, il le testera simplement plus avant pour quel type mime connu et prendra les mesures nécessaires. Je pense que IE essaie de faire cela en premier 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 de fichier à partir du système de fichiers ou de l'entrée de 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 fiables à ce sujet.
la source
Cela dépend probablement du système d'exploitation et peut-être 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 de 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.
la source
Bien que ce ne soit pas une réponse à votre question, cela résout le problème que vous essayez de résoudre. YMMV.
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 d'origine (y compris l'extension) du fichier. La meilleure façon de résoudre le problème est donc d'inspecter l'extension du fichier au lieu du type MIME.
Si vous avez toujours besoin du type mime, vous pouvez utiliser les types mime.types de votre propre apache pour le déterminer côté serveur.
la source
Je suis d'accord avec johndodo, il y a tellement de variables qui rendent les types mime envoyés par les navigateurs peu fiables. J'exclurais les sous-types qui sont reçus et me concentrerais simplement 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 simplement l'extension du fichier pour vous assurer qu'il s'agit bien de .zip ou de toute autre compression que vous recherchez!
la source
Selon rfc1867 - Téléchargement de fichier basé sur un formulaire en HTML :
Donc, je crois comprendre,
application/octet-stream
c'est un peu comme unblanket catch-all
identificateur si le type ne peut pas être déduit .la source
application/octet-stream
c'est le fourre-tout, alors une autre approche serait de faire confiance au navigateur s'il a pu faire une estimation, et de faire vos propres tests côté serveur si vous obtenezapplication/octet-stream
.