Mam aplikację internetową, w której użytkownik musi przesłać plik .zip. Po stronie serwera sprawdzam typ MIME przesłanego pliku, aby upewnić się, że jest to application/x-zip-compressed
lub application/zip
.
To działało dobrze dla mnie w Firefoksie i IE. Jednak gdy współpracownik go przetestował, nie udało mu się to w Firefoksie (wysłany typ MIME to coś w rodzaju „ application/octet-stream
”), ale działał w przeglądarce Internet Explorer. Nasze konfiguracje wydają się identyczne: IE8, FF 3.5.1 z wyłączonymi wszystkimi dodatkami, Win XP SP3, WinRAR zainstalowany jako natywny program obsługi plików .zip (nie jestem pewien, czy to istotne).
Więc moje pytanie brzmi: jaki sposób przeglądarka określa, jaki typ MIME wysłać?
Uwaga: wiem, że typ MIME jest wysyłany przez przeglądarkę i dlatego jest zawodny. Sprawdzam to tylko dla wygody - głównie po to, aby dać bardziej przyjazny komunikat o błędzie niż te, które otrzymujesz, próbując otworzyć plik niezip jako plik zip, i aby uniknąć ładowania (prawdopodobnie ciężkich) bibliotek plików zip.
źródło
input/@formenctype
lubform/@enctype
atrybutyOdpowiedzi:
Chrom
Chrome (wersja 38 w chwili pisania) ma 3 sposoby określenia typu MIME i robi to w określonej kolejności. Poniższy fragment pochodzi z pliku
src/net/base/mime_util.cc
, metodaMimeUtil::GetMimeTypeFromExtensionHelper
.Zakodowane listy pojawiają się nieco wcześniej w pliku: https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170 (
kPrimaryMappings
ikSecondaryMappings
).Przykład: podczas przesyłania pliku CSV z systemu Windows z zainstalowanym programem Microsoft Excel Chrome zgłosi to jako
application/vnd.ms-excel
. Dzieje się tak, ponieważ.csv
nie jest określony na pierwszej zakodowanej liście, więc przeglądarka powraca do rejestru systemu.HKEY_CLASSES_ROOT\.csv
ma wartość o nazwie,Content Type
która jest ustawiona naapplication/vnd.ms-excel
.Internet Explorer
Ponownie korzystając z tego samego przykładu, przeglądarka zgłosi
application/vnd.ms-excel
. Myślę, że rozsądne jest założenie, że Internet Explorer (wersja 11 w chwili pisania) korzysta z rejestru. Możliwe, że korzysta również z zakodowanej listy, takiej jak Chrome i Firefox, ale jej zamknięty charakter źródłowy utrudnia weryfikację.Firefox
Jak wskazano w kodzie Chrome, Firefox (wersja 32 w chwili pisania) działa w podobny sposób. Fragment z pliku
uriloader\exthandler\nsExternalHelperAppService.cpp
, metodansExternalHelperAppService::GetTypeFromExtension
Listy zakodowane na stałe znajdują się wcześniej w pliku, gdzieś w pobliżu linii 441. Szukasz
defaultMimeEntries
iextraMimeEntries
.W przypadku mojego obecnego profilu przeglądarka zgłosi raport,
text/csv
ponieważ jest dla niego wpismimeTypes.rdf
(pozycja 2 na powyższej liście). Przy nowym profilu, który nie ma tego wpisu, przeglądarka zgłosiapplication/vnd.ms-excel
(pozycja 3 na liście).Podsumowanie
Zakodowane na stałe listy w przeglądarkach są dość ograniczone. Często typ MIME wysłany przez przeglądarkę będzie taki, jaki jest zgłaszany przez system operacyjny. I właśnie dlatego, jak stwierdzono w pytaniu, typ MIME zgłaszany przez przeglądarkę jest niewiarygodny.
źródło
Kip, spędziłem trochę czasu na czytaniu RFC, MSDN i MDN. Oto, co mogłem zrozumieć. Gdy przeglądarka napotyka plik do przesłania, sprawdza pierwszy bufor danych, które otrzymuje, a następnie przeprowadza na nim test. Te testy próbują określić, czy plik jest znanym typem MIME, czy nie, a jeśli jest znany typ MIME, po prostu dalej go przetestuje, dla którego znanego typu MIME, i podejmie odpowiednie działania. Myślę, że IE próbuje to zrobić najpierw, a nie tylko określa typ pliku na podstawie rozszerzenia. Ta strona wyjaśnia to dla IE http://msdn.microsoft.com/en-us/library/ms775147%28v=vs.85%29.aspx . W przypadku Firefoksa mogłem zrozumieć, że próbuje odczytać informacje o pliku z systemu plików lub wpisu katalogu, a następnie określa typ pliku. Oto link do FF https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIFile. Nadal chciałbym mieć więcej wiarygodnych informacji na ten temat.
źródło
Jest to prawdopodobnie zależne od systemu operacyjnego i prawdopodobnie przeglądarki, ale w systemie Windows typ MIME dla danego rozszerzenia pliku można znaleźć w rejestrze pod HKCR:
Na przykład:
HKEY_CLASSES_ROOT.zip - ContentType
Aby przejść z MIME do rozszerzenia pliku, możesz spojrzeć na klawisze poniżej
HKEY_CLASSES_ROOT \ Mime \ Database \ Content Type
Aby uzyskać domyślne rozszerzenie dla określonego typu MIME.
źródło
Chociaż nie jest to odpowiedź na Twoje pytanie, rozwiązuje problem, który próbujesz rozwiązać. YMMV.
Jak napisałeś, typ MIME nie jest wiarygodny, ponieważ każda przeglądarka ma swój sposób określania go. Jednak przeglądarki wysyłają oryginalną nazwę (łącznie z rozszerzeniem) pliku. Dlatego najlepszym sposobem rozwiązania problemu jest sprawdzenie rozszerzenia pliku zamiast typu MIME.
Jeśli nadal potrzebujesz typu mime, możesz użyć własnego typu mime.types Apache, aby określić go po stronie serwera.
źródło
Zgadzam się z johndodo, jest tak wiele zmiennych, które powodują, że typy MIME wysyłane z przeglądarek są niewiarygodne. Wykluczyłbym otrzymane podtypy i skupiłbym się tylko na typie „aplikacja”. jeśli Twoja aplikacja jest oparta na PHP, możesz to łatwo zrobić za pomocą funkcji explode (). ponadto po prostu sprawdź rozszerzenie pliku, aby upewnić się, że jest to .zip lub inna kompresja, której szukasz!
źródło
Zgodnie z rfc1867 - przesyłanie plików w formacie HTML na podstawie formularza :
Rozumiem więc, że jest
application/octet-stream
to rodzajblanket catch-all
identyfikatora, jeśli nie można wywnioskować typu .źródło
application/octet-stream
chodzi o wszystko, innym podejściem byłoby zaufanie przeglądarce, jeśli byłaby w stanie zgadnąć, i wykonanie własnych testów po stronie serwera, jeśli tak się stanieapplication/octet-stream
.