У меня есть веб-приложение, в котором пользователю нужно загрузить файл .zip. На стороне сервера я проверяю MIME-тип загруженного файла, чтобы убедиться, что это application/x-zip-compressed
или application/zip
.
У меня это отлично сработало в Firefox и IE. Однако, когда его коллега протестировал его, в Firefox это не помогло (отправленный тип пантомимы был чем-то вроде " application/octet-stream
"), но работал в Internet Explorer. Наши настройки кажутся идентичными: IE8, FF 3.5.1 со всеми отключенными надстройками, Win XP SP3, WinRAR установлен как собственный обработчик файлов .zip (не уверен, что это актуально).
Итак, мой вопрос: как браузер определяет, какой тип MIME отправлять?
Обратите внимание: я знаю, что тип mime отправляется браузером и, следовательно, ненадежен. Я просто проверяю это для удобства - в основном, чтобы дать более понятное сообщение об ошибке, чем те, которые вы получаете, пытаясь открыть не-zip-файл в виде zip-файла, и чтобы избежать загрузки (предположительно тяжелых) библиотек zip-файлов.
input/@formenctype
илиform/@enctype
Ответы:
Хром
Chrome (версия 38 на момент написания) имеет 3 способа определения типа MIME и делает это в определенном порядке. Приведенный ниже фрагмент взят из файла
src/net/base/mime_util.cc
, методаMimeUtil::GetMimeTypeFromExtensionHelper
.Жестко запрограммированные списки находятся в файле немного раньше: https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170 (
kPrimaryMappings
иkSecondaryMappings
).Пример: при загрузке файла CSV из системы Windows с установленным Microsoft Excel, Chrome сообщит об этом как
application/vnd.ms-excel
. Это связано с тем, что.csv
он не указан в первом жестко запрограммированном списке, поэтому браузер возвращается к системному реестру.HKEY_CLASSES_ROOT\.csv
имеет значение с именемContent Type
, равнымapplication/vnd.ms-excel
.Internet Explorer
Опять же, используя тот же пример, браузер сообщит
application/vnd.ms-excel
. Я думаю, что разумно предположить, что Internet Explorer (версия 11 на момент написания) использует реестр. Возможно, он также использует жестко запрограммированный список, такой как Chrome и Firefox, но его закрытый исходный код затрудняет проверку.Fire Fox
Как указано в коде Chrome, Firefox (версия 32 на момент написания) работает аналогичным образом. Фрагмент из файла
uriloader\exthandler\nsExternalHelperAppService.cpp
, методnsExternalHelperAppService::GetTypeFromExtension
Жестко запрограммированные списки находятся в файле раньше, где-то рядом со строкой 441. Вы ищете
defaultMimeEntries
иextraMimeEntries
.В моем текущем профиле браузер сообщит об этом,
text/csv
потому что для него есть записьmimeTypes.rdf
(пункт 2 в списке выше). При новом профиле, в котором нет этой записи, браузер отправит отчетapplication/vnd.ms-excel
(пункт 3 в списке).Резюме
Жестко заданные списки в браузерах довольно ограничены. Часто тип MIME, отправляемый браузером, совпадает с типом, сообщенным ОС. И именно поэтому, как указано в вопросе, тип MIME, сообщаемый браузером, ненадежен.
источник
Кип, я некоторое время читал RFC, MSDN и MDN. Вот что я смог понять. Когда браузер встречает файл для загрузки, он просматривает первый буфер данных, который он получает, а затем запускает на нем тест. Эти тесты пытаются определить, является ли файл известным типом MIME или нет, и, если известен тип MIME, он просто дополнительно проверит его на предмет того, какой из известных типов MIME и предпримет соответствующие действия. Я думаю, что IE пытается сначала сделать это, а не просто определять тип файла по расширению. На этой странице объясняется это для IE http://msdn.microsoft.com/en-us/library/ms775147%28v=vs.85%29.aspx . Что касается firefox, я понял, что он пытается прочитать информацию о файле из файловой системы или записи каталога, а затем определяет тип файла. Вот ссылка на FF https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIFile. Я все еще хотел бы получить более авторитетную информацию по этому поводу.
источник
Вероятно, это зависит от ОС и, возможно, браузера, но в Windows тип MIME для данного расширения файла можно найти, заглянув в реестр в разделе HKCR:
Например:
HKEY_CLASSES_ROOT.zip - ContentType
Чтобы перейти от MIME к расширению файла, вы можете посмотреть ключи под
HKEY_CLASSES_ROOT \ Mime \ Database \ Тип содержимого
Чтобы получить расширение по умолчанию для определенного типа MIME.
источник
Хотя это не ответ на ваш вопрос, он решает проблему, которую вы пытаетесь решить. YMMV.
Как вы писали, тип MIME ненадежен, поскольку каждый браузер определяет его по-своему. Однако браузеры отправляют исходное имя (включая расширение) файла. Итак, лучший способ справиться с проблемой - проверить расширение файла, а не тип MIME.
Если вам все еще нужен тип mime, вы можете использовать свой собственный apache mime.types, чтобы определить его на стороне сервера.
источник
Я согласен с johndodo, существует так много переменных, которые делают типы mime, отправляемые из браузеров, ненадежными. Я бы исключил полученные подтипы и сосредоточился только на таком типе, как «приложение». если ваше приложение основано на php, вы можете легко сделать это с помощью функции explode (). Кроме того, просто проверьте расширение файла, чтобы убедиться, что это .zip или любое другое сжатие, которое вы ищете!
источник
Согласно rfc1867 - загрузка файла на основе формы в HTML :
Таким образом , мое понимание,
application/octet-stream
это вроде какblanket catch-all
идентификатор , если тип не может быть выведен .источник
application/octet-stream
это уловка, то другим подходом было бы доверие браузеру, если он смог сделать предположение, и проведение собственных тестов на стороне сервера, если оно получилосьapplication/octet-stream
.