Ich habe eine Web-App, in die der Benutzer eine ZIP-Datei hochladen muss. Auf der Serverseite überprüfe ich den MIME-Typ der hochgeladenen Datei, um sicherzustellen, dass es sich um application/x-zip-compressed
oder handelt application/zip
.
Dies funktionierte gut für mich unter Firefox und IE. Als ein Mitarbeiter es testete, schlug es für ihn in Firefox fehl (gesendeter MIME-Typ war so etwas wie " application/octet-stream
"), funktionierte jedoch in Internet Explorer. Unsere Setups scheinen identisch zu sein: IE8, FF 3.5.1 mit allen deaktivierten Add-Ons, Win XP SP3, WinRAR als nativer ZIP-Dateihandler installiert (nicht sicher, ob dies relevant ist).
Meine Frage lautet also: Wie bestimmt der Browser, welchen MIME-Typ gesendet werden soll?
Bitte beachten Sie: Ich weiß, dass der MIME-Typ vom Browser gesendet wird und daher unzuverlässig ist. Ich überprüfe es nur als Annehmlichkeit - hauptsächlich, um eine freundlichere Fehlermeldung als die zu erhalten, die Sie erhalten, wenn Sie versuchen, eine Nicht-Zip-Datei als Zip-Datei zu öffnen, und um das Laden der (vermutlich schweren) Zip-Dateibibliotheken zu vermeiden.
quelle
input/@formenctype
form/@enctype
Antworten:
Chrom
Chrome (Version 38 zum Zeitpunkt des Schreibens) bietet drei Möglichkeiten, um den MIME-Typ zu bestimmen, und zwar in einer bestimmten Reihenfolge. Das folgende Snippet stammt aus der Datei
src/net/base/mime_util.cc
, MethodeMimeUtil::GetMimeTypeFromExtensionHelper
.Die fest codierten Listen befinden sich etwas früher in der Datei: https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170 (
kPrimaryMappings
undkSecondaryMappings
).Ein Beispiel: Wenn Sie eine CSV-Datei von einem Windows-System mit installiertem Microsoft Excel hochladen, meldet Chrome dies als
application/vnd.ms-excel
. Dies liegt daran, dass.csv
in der ersten fest codierten Liste nichts angegeben ist, sodass der Browser auf die Systemregistrierung zurückgreift.HKEY_CLASSES_ROOT\.csv
hat einen Wert namensContent Type
, der auf gesetzt istapplication/vnd.ms-excel
.Internet Explorer
Wiederum mit demselben Beispiel meldet der Browser
application/vnd.ms-excel
. Ich denke, es ist vernünftig anzunehmen, dass Internet Explorer (Version 11 zum Zeitpunkt des Schreibens) die Registrierung verwendet. Möglicherweise wird auch eine fest codierte Liste wie Chrome und Firefox verwendet, die jedoch aufgrund ihrer Closed-Source-Natur schwer zu überprüfen ist.Feuerfuchs
Wie im Chrome-Code angegeben, funktioniert Firefox (Version 32 zum Zeitpunkt des Schreibens) auf ähnliche Weise. Ausschnitt aus Datei
uriloader\exthandler\nsExternalHelperAppService.cpp
, MethodensExternalHelperAppService::GetTypeFromExtension
Die fest codierten Listen befinden sich früher in der Datei, irgendwo in der Nähe von Zeile 441. Sie suchen nach
defaultMimeEntries
undextraMimeEntries
.Bei meinem aktuellen Profil meldet der Browser,
text/csv
weil inmimeTypes.rdf
(Punkt 2 in der obigen Liste) ein Eintrag dafür vorhanden ist . Bei einem neuen Profil, das diesen Eintrag nicht enthält, meldet der Browserapplication/vnd.ms-excel
(Punkt 3 in der Liste).Zusammenfassung
Die fest codierten Listen in den Browsern sind ziemlich begrenzt. Häufig ist der vom Browser gesendete MIME-Typ der vom Betriebssystem gemeldete. Und genau aus diesem Grund ist der vom Browser gemeldete MIME-Typ, wie in der Frage angegeben, unzuverlässig.
quelle
Kip, ich habe einige Zeit damit verbracht, RFCs, MSDN und MDN zu lesen. Folgendes konnte ich verstehen. Wenn ein Browser auf eine Datei zum Hochladen stößt, überprüft er den ersten empfangenen Datenpuffer und führt dann einen Test durch. Diese Tests versuchen festzustellen, ob die Datei ein bekannter MIME-Typ ist oder nicht, und wenn ein bekannter MIME-Typ vorliegt, wird sie einfach weiter getestet, für welchen bekannten MIME-Typ, und entsprechende Maßnahmen ergriffen. Ich denke, der IE versucht dies zuerst zu tun, anstatt nur den Dateityp anhand der Erweiterung zu bestimmen. Diese Seite erklärt dies für IE http://msdn.microsoft.com/en-us/library/ms775147%28v=vs.85%29.aspx . Für Firefox konnte ich verstehen, dass es versucht, Dateiinformationen aus dem Dateisystem oder dem Verzeichniseintrag zu lesen und dann den Dateityp bestimmt. Hier ist ein Link für FF https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIFile. Ich hätte gerne noch maßgeblichere Informationen dazu.
quelle
Dies ist wahrscheinlich vom Betriebssystem und möglicherweise vom Browser abhängig. Unter Windows kann der MIME-Typ für eine bestimmte Dateierweiterung in der Registrierung unter HKCR gefunden werden:
Beispielsweise:
HKEY_CLASSES_ROOT.zip - ContentType
Um von MIME zur Dateierweiterung zu gelangen, können Sie sich die Schlüssel unter ansehen
HKEY_CLASSES_ROOT \ Mime \ Database \ Content Type
Abrufen der Standarderweiterung für einen bestimmten MIME-Typ.
quelle
Dies ist zwar keine Antwort auf Ihre Frage, löst jedoch das Problem, das Sie lösen möchten. YMMV.
Wie Sie geschrieben haben, ist der MIME-Typ nicht zuverlässig, da jeder Browser seine Art hat, ihn zu bestimmen. Browser senden jedoch den ursprünglichen Namen (einschließlich der Erweiterung) der Datei. Der beste Weg, um das Problem zu lösen, besteht darin, die Erweiterung der Datei anstelle des MIME-Typs zu überprüfen.
Wenn Sie den MIME-Typ weiterhin benötigen, können Sie die MIME-Typen Ihres eigenen Apachen verwenden, um ihn serverseitig zu bestimmen.
quelle
Ich stimme Johndodo zu, es gibt so viele Variablen, die MIME-Typen, die von Browsern gesendet werden, unzuverlässig machen. Ich würde die empfangenen Untertypen ausschließen und mich nur auf den Typ wie "Anwendung" konzentrieren. Wenn Ihre App PHP-basiert ist, können Sie dies einfach mit der Funktion explode () tun. Überprüfen Sie außerdem einfach die Dateierweiterung, um sicherzustellen, dass es sich um .zip oder eine andere gewünschte Komprimierung handelt!
quelle
Laut rfc1867 - Formularbasierter Datei-Upload in HTML :
Mein Verständnis ist also,
application/octet-stream
ist wie eineblanket catch-all
Kennung, wenn der Typ nicht abgeleitet werden kann .quelle
application/octet-stream
der Haken ist, besteht ein anderer Ansatz darin, dem Browser zu vertrauen, wenn er eine Vermutung anstellen konnte, und gegebenenfalls Ihre eigenen serverseitigen Tests durchzuführenapplication/octet-stream
.