MIME-типы

Ищите в справочной таблице распространённых расширений файлов и их MIME-типов IANA, отфильтрованных по верхнеуровневой категории, чтобы каждый раз задавать правильный заголовок Content-Type.

Какой заголовок Content-Type нужен этому файлу? Введите расширение, например .webp, или часть медиа-типа, например image, чтобы отфильтровать таблицу. Каждая запись следует реестру медиа-типов IANA и списку распространённых типов MDN.

Совпадения
Расширение MIME-тип

Что браузеру сообщает MIME-тип

Устройство медиа-типа

MIME-тип — правильнее называемый медиа-типом — это метка, которую сервер прикрепляет к ответу, чтобы клиент знал, как обработать следующие байты. Он состоит из двух частей, разделённых слэшем: верхнеуровневого типа, такого как text, image, audio, video, font, model или application, и подтипа, называющего конкретный формат. image/png и application/json — оба полные медиа-типы; одного image недостаточно.

Подтипы имеют свои соглашения. Ведущий x- когда-то отмечал экспериментальный тип, как в application/x-tar, и хотя практика устарела, сохранившиеся имена слишком широко распространены, чтобы их менять. Завершающий +suffix говорит, что формат построен на более общем синтаксисе: image/svg+xml — это XML, application/ld+json — это JSON, и парсер может откатиться к базовому синтаксису, когда не распознаёт конкретный формат.

Некоторые типы принимают параметры после точки с запятой. Самый важный — charset, как в text/html; charset=utf-8. Его отсутствие в текстовом ответе провоцирует браузер угадывать кодировку, что — классический источник mojibake, поэтому явное указание UTF-8 всегда стоит лишних символов.

Почему заголовок важнее расширения

Браузер решает, что делать с ответом, на основе заголовка Content-Type, а не имени файла в URL. Отдавая PNG как text/plain, вы увидите стену двоичного мусора; отдавая JSON как text/html, можно заставить fetch-клиента отвергнуть его. Правильный заголовок — это то, что открывает загрузку в нужном приложении и отрисовывает встроенный ресурс вместо скачивания.

Несоответствие имеет и последствия для безопасности. Старые браузеры практиковали MIME-сниффинг, осматривая первые байты ответа и переопределяя заголовок, который считали неверным. Злоумышленник, способный загрузить файл, похожий на HTML, мог заставить выполнить его в origin сайта, даже когда сервер пометил его как изображение. Заголовок X-Content-Type-Options: nosniff отключает это поведение и теперь является стандартной практикой на любой конечной точке, отдающей загруженное пользователями содержимое.

Для скачиваний сочетайте медиа-тип с Content-Disposition: attachment; filename="report.pdf". Медиа-тип описывает, что собой представляют байты, а disposition описывает, что браузер должен с ними сделать — они отвечают на разные вопросы.

Где на самом деле живёт сопоставление

Единой авторитетной таблицы «расширение — тип» не существует, и это удивляет людей. IANA регистрирует сами медиа-типы, но сопоставление от расширения файла к типу — это локальное соглашение, которое ведёт каждый сервер. Apache читает mime.types, nginx имеет свой файл mime.types, а фреймворки поставляются со своими таблицами поиска. Поэтому один и тот же файл .wasm может быть отдан правильно одним сервером и как application/octet-stream другим, который не обновлялся.

application/octet-stream — это общий запасной вариант со значением «произвольные двоичные данные». Это честный ответ, когда формат действительно неизвестен, но он отменяет встроенную отрисовку, поэтому стоит добавить явное сопоставление для любого формата, который ваш сайт регулярно отдаёт. Более новые форматы, такие как AVIF, JXL и WebAssembly, чаще всего отсутствуют в старой конфигурации сервера.

Примечание об открытом исходном коде: реализовано на чистом JavaScript без сторонних библиотек.

Часто задаваемые вопросы

Почему мой файл скачивается вместо отображения?
Либо медиа-тип — `application/octet-stream`, либо ответ несёт `Content-Disposition: attachment`. Задайте правильный тип и уберите disposition вложения, чтобы отрисовать встроенно.
Каков MIME-тип для JSON?
`application/json`. Старый код иногда использовал `text/json` или `application/x-json`, но ни один из них не зарегистрирован, и некоторые клиенты отвергают их.
Должен ли JavaScript быть text/javascript или application/javascript?
`text/javascript` — рекомендуемая сейчас форма. Обе работают в каждом браузере, но спецификация HTML остановилась на текстовом варианте и помечает application-вариант как устаревший.
Нужно ли указывать charset?
Для текстовых типов — да. Без него браузер угадывает, что даёт mojibake для не-ASCII содержимого. Отправляйте `text/html; charset=utf-8` или эквивалент для вашего типа.
Что означает суффикс +xml или +json?
Что формат построен на более общем синтаксисе. Клиент, который не знает конкретно `application/ld+json`, всё равно может разобрать его как JSON, что делает возможным универсальный инструментарий.
Почему мой сервер отдаёт неверный тип для .webp или .avif?
Расширение отсутствует в файле `mime.types` этого сервера. Добавьте явное сопоставление в конфигурацию сервера; сам файл в порядке и не требует изменений.