Открыть сервис

Multipart

Multipart — это формат передачи данных, применяемый в протоколах прикладного уровня (прежде всего в HTTP и электронной почте), который позволяет в рамках одного сообщения или ответа объединять несколько независимых частей (блоков) данных, каждая из которых может иметь собственный тип содержимого, кодировку и метаданные. Основное назначение multipart — обеспечить возможность передачи в одном пакете разнородных данных, таких как текст, изображения, вложения файлов, а также фрагменты, предназначенные для частичного обновления веб-страницы (например, в технологии Server-Sent Events или при загрузке файлов формами).

История и стандартизация

Формат multipart был впервые определён в спецификации MIME (Multipurpose Internet Mail Extensions) в начале 1990-х годов как расширение для протокола SMTP, позволяющее отправлять электронные письма с вложениями и нетекстовым содержимым. Первоначально стандарт MIME был описан в документах RFC 1341 и RFC 1521 (1993 год), а затем уточнён в RFC 2045–2049 (1996 год). С развитием веба формат multipart был адаптирован для протокола HTTP: в частности, для отправки данных HTML-форм с загрузкой файлов (тип multipart/form-data) и для передачи составных ответов сервера (тип multipart/mixed). Позднее появились специализированные подтипы, такие как multipart/byteranges для частичной загрузки ресурсов (HTTP Range Requests) и multipart/alternative для предоставления одного и того же содержимого в разных форматах (например, текст и HTML).

Структура multipart-сообщения

Любое multipart-сообщение состоит из следующих обязательных элементов:

  • Заголовок Content-Type с указанием подтипа multipart (например, multipart/form-data) и параметра boundary — уникальной строки-разделителя, которая не должна встречаться внутри данных частей.
  • Преамбула — необязательный текст перед первой границей (часто игнорируется обработчиками).
  • Одна или несколько частей (part), каждая из которых отделяется от предыдущей строкой --boundary. Каждая часть содержит собственные заголовки (например, Content-Type, Content-Disposition, Content-Transfer-Encoding) и тело (содержимое).
  • Эпилог — необязательный текст после последней границы (обычно пустой).
  • Завершающая граница — строка --boundary--, обозначающая конец всего multipart-сообщения.

Формат гарантирует, что граница не встречается внутри данных ни одной из частей, что достигается выбором достаточно длинной и случайной строки (например, на основе UUID или хеша).

Основные подтипы multipart

multipart/mixed

Используется для передачи разнородных данных, которые должны быть обработаны как единое целое, но могут быть разделены получателем. Наиболее распространён в электронной почте для вложений: письмо может содержать текстовую часть и прикреплённые файлы (изображения, документы). В HTTP применяется реже, например, в ответах серверов, возвращающих несколько независимых ресурсов.

multipart/alternative

Предназначен для предоставления одного и того же содержимого в нескольких форматах (например, plain text и HTML). Получатель (почтовый клиент или браузер) выбирает наиболее подходящий формат на основе своих возможностей. Части располагаются в порядке возрастания сложности: первая — самый простой вариант (обычно текст), последняя — наиболее насыщенный (HTML).

multipart/form-data

Специализированный подтип, определённый в RFC 2388 (1998 год) для отправки данных HTML-форм с возможностью загрузки файлов. Каждая часть соответствует одному полю формы (например, текстовому полю или файлу). Для каждой части обязательно указывается заголовок Content-Disposition: form-data; name="имя_поля", а для файлов — дополнительно filename="имя_файла". Этот подтип широко используется в современных веб-приложениях при отправке форм через HTTP-метод POST с типом содержимого multipart/form-data.

multipart/byteranges

Применяется в протоколе HTTP для ответа на запрос с заголовком Range, когда клиент запрашивает несколько фрагментов ресурса (например, для докачки или параллельной загрузки). Каждая часть содержит один диапазон байтов с указанием в заголовке Content-Range. Ответ сервера в этом случае имеет статус 206 Partial Content.

multipart/encrypted и multipart/signed

Используются в криптографических протоколах (например, S/MIME) для защиты содержимого электронных писем. multipart/encrypted содержит зашифрованные данные и информацию о способе шифрования, а multipart/signed — исходное сообщение и его цифровую подпись.

multipart/related

Определён в RFC 2387 для передачи составных документов, где одна часть является корневой (например, HTML-страница), а остальные — связанные с ней ресурсы (изображения, стили, скрипты). В отличие от multipart/mixed, здесь части логически взаимосвязаны, и корневая часть может ссылаться на другие части по идентификаторам (Content-ID).

Применение в веб-технологиях

В веб-разработке multipart-формат наиболее часто встречается в двух контекстах:

Отправка форм с файлами

При использовании HTML-форм с атрибутом enctype="multipart/form-data" браузер кодирует все поля формы (включая файлы) в одно HTTP-сообщение с типом multipart/form-data. Это единственный стандартный способ передачи бинарных данных через веб-формы. Серверная часть (например, PHP, Node.js, Python) должна корректно разбирать такое сообщение, извлекая каждое поле и файл. При этом важно учитывать ограничения на размер загружаемых файлов, устанавливаемые как на стороне клиента, так и на стороне сервера.

Составные ответы сервера

Некоторые веб-приложения используют multipart/mixed или multipart/related для передачи в одном HTTP-ответе нескольких независимых ресурсов (например, HTML-страницы и связанных с ней изображений) без дополнительных запросов. Однако на практике этот подход уступил место более эффективным методам, таким как встраивание ресурсов в CSS/JavaScript (data: URI) или использование HTTP/2 Server Push.

Ограничения и особенности

  • Размер сообщения: Multipart-сообщения могут быть значительно больше, чем сумма размеров их частей, из-за накладных расходов на границы и заголовки. Для больших файлов это может приводить к избыточности.
  • Сложность парсинга: Корректный разбор multipart-сообщения требует точного соблюдения спецификации, включая обработку границ, кодировок и переносов строк. Некорректные реализации могут приводить к уязвимостям (например, атакам с подделкой границ).
  • Поддержка в браузерах: Все современные браузеры поддерживают отправку multipart/form-data через формы и объект FormData в JavaScript. Однако при работе с другими подтипами (например, multipart/alternative в ответах сервера) поддержка может быть ограничена.
  • Безопасность: При загрузке файлов через multipart-формы сервер должен проверять тип содержимого, размер и имя файла, чтобы предотвратить атаки (например, загрузку исполняемых скриптов). Рекомендуется использовать белые списки разрешённых типов и переименовывать загружаемые файлы.

Примеры использования

Электронная почта

Почтовый клиент отправляет письмо в формате multipart/alternative, содержащее две части: первую — с текстом в кодировке plain text, вторую — с HTML-версией. Получатель может просматривать письмо в зависимости от настроек своего клиента.

Веб-форма

Пользователь заполняет форму на сайте, включающую текстовое поле «имя» и поле для загрузки фотографии. Браузер формирует HTTP-запрос POST с типом multipart/form-data, где одна часть содержит строку «Иван», а другая — бинарные данные файла с заголовком Content-Disposition: form-data; name="photo"; filename="photo.jpg".

Частичная загрузка

Клиент запрашивает два фрагмента видеофайла: первые 1000 байт и байты с 5000 по 6000. Сервер возвращает ответ с типом multipart/byteranges, содержащий две части, каждая с соответствующим диапазоном.

Источники

  • RFC 2045 — Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies
  • RFC 2046 — Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types
  • RFC 2388 — Returning Values from Forms: multipart/form-data
  • RFC 7233 — Hypertext Transfer Protocol (HTTP/1.1): Range Requests
  • RFC 2387 — The MIME Multipart/Related Content-type

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →