Что означает enctype = 'multipart/form-data'?

Что означает enctype='multipart/form-data' в форме HTML и когда мы должны его использовать?

Ответ 1

Когда вы делаете запрос POST, вы должны каким-то образом кодировать данные, которые формируют тело запроса.

HTML-формы предоставляют три метода кодирования.

  • application/x-www-form-urlencoded (по умолчанию)
  • multipart/form-data
  • text/plain

Работа над добавлением application/json была сделана, но это было прекращено.

(Другие кодировки возможны с HTTP-запросами, сгенерированными с использованием других средств, кроме отправки HTML-форм.)

Специфика форматов не имеет значения для большинства разработчиков. Важными моментами являются:

  • Никогда не используйте text/plain.

Когда вы пишете код на стороне клиента:

  • используйте multipart/form-data когда ваша форма содержит какие-либо элементы <input type="file">
  • в противном случае вы можете использовать multipart/form-data или application/x-www-form-urlencoded но application/x-www-form-urlencoded будет более эффективным

Когда вы пишете код на стороне сервера:

  • Используйте заранее написанную библиотеку обработки форм

Большинство (например, Perl CGI->param или тот, который представлен в PHP $_POST superglobal) позаботятся о различиях за вас. Не пытайтесь анализировать необработанные данные, полученные сервером.

Иногда вы найдете библиотеку, которая не может обрабатывать оба формата. Наиболее популярной библиотекой Node.js для обработки данных форм является body-parser, который не может обрабатывать многокомпонентные запросы (но имеет документацию, которая рекомендует некоторые альтернативы, которые могут).


Если вы пишете (или отлаживаете) библиотеку для анализа или генерации необработанных данных, вам нужно начать беспокоиться о формате. Вы также можете узнать об этом ради интереса.

application/x-www-form-urlencoded более или менее совпадает со строкой запроса в конце URL.

multipart/form-data значительно сложнее, но позволяет включать в данные целые файлы. Пример результата можно найти в спецификации HTML 4.

text/plain введен в HTML 5 и полезен только для отладки - из спецификации: они не могут быть надежно интерпретированы компьютером - и я бы сказал, что другие объединены с инструментами (например, вкладка Net в инструментах разработчика большинства браузеров) ) лучше для этого).

Ответ 2

когда мы должны использовать это

Ответ Квентина верен: используйте multipart/form-data если форма содержит загружаемый файл, и application/x-www-form-urlencoded противном случае, что является значением по умолчанию, если вы опускаете enctype.

Я собираюсь:

  • добавить еще несколько ссылок HTML5
  • объясните почему он прав с помощью примера

HTML5 ссылки

Есть три возможности для enctype:

  • application/x-www-form-urlencoded
  • multipart/form-data (спецификация указывает на RFC7578)
  • text/plain Это "ненадежно интерпретируется компьютером", поэтому никогда не должно использоваться в производстве, и мы не будем вдаваться в подробности.

Как генерировать примеры

Как только вы видите пример каждого метода, становится очевидным, как они работают, и когда вы должны использовать каждый из них.

Вы можете привести примеры, используя:

Сохраните форму в минимальный файл .html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <title>upload</title>
</head>
<body>
<form action="http://localhost:8000" method="post" enctype="multipart/form-data">
  <p><input type="text" name="text1" value="text default">
  <p><input type="text" name="text2" value="a&#x03C9;b">
  <p><input type="file" name="file1">
  <p><input type="file" name="file2">
  <p><input type="file" name="file3">
  <p><button type="submit">Submit</button>
</form>
</body>
</html>

Мы устанавливаем текстовое значение по умолчанию a&#x03C9;b, что означает aωb потому что ω равно U+03C9, которые являются байтами 61 CF 89 62 в UTF-8.

Создайте файлы для загрузки:

echo 'Content of a.txt.' > a.txt

echo '<!DOCTYPE html><title>Content of a.html.</title>' > a.html

# Binary file containing 4 bytes: 'a', 1, 2 and 'b'.
printf 'a\xCF\x89b' > binary

Запустите наш маленький эхо-сервер:

while true; do printf '' | nc -l 8000 localhost; done

Откройте HTML в вашем браузере, выберите файлы, нажмите "Отправить" и проверьте терминал.

nc печатает полученный запрос.

Проверено на: Ubuntu 14.04.3, nc BSD 1.105, Firefox 40.

многочастному/форм-данных,

Firefox отправил:

POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150
Content-Length: 834

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text1"

text default
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text2"

aωb
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain

Content of a.txt.

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file2"; filename="a.html"
Content-Type: text/html

<!DOCTYPE html><title>Content of a.html.</title>

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file3"; filename="binary"
Content-Type: application/octet-stream

aωb
-----------------------------735323031399963166993862150--

Для двоичного файла и текстового поля байты 61 CF 89 62 (aωb в UTF-8) отправляются буквально. Вы можете проверить это с помощью nc -l localhost 8000 | hd nc -l localhost 8000 | hd, который говорит, что байты:

61 CF 89 62

были отправлены (61 == 'a' и 62 == 'b').

Поэтому ясно, что:

  • Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266 Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266 устанавливает тип содержимого multipart/form-data и говорит, что поля разделены заданной boundary строкой.

  • каждое поле получает несколько подзаголовков перед своими данными: Content-Disposition: form-data; , name поля, name filename, а затем данные.

    Сервер читает данные до следующей граничной строки. Браузер должен выбрать границу, которая не будет отображаться ни в одном из полей, поэтому эта граница может варьироваться между запросами.

    Поскольку у нас есть уникальная граница, кодирование данных не требуется: двоичные данные отправляются как есть.

    TODO: каков оптимальный размер границы (log(N) я ставлю) и название/время работы алгоритма, который его находит? На вопрос: https://cs.stackexchange.com/questions/39687/find-the-shortest-sequence-that-is-not-a-sub-sequence-of-a-set-of-sequence

  • Content-Type автоматически определяется браузером.

    Как именно это определяется, было задано по адресу: Как браузер определяет тип mime загруженного файла?

применение/х-WWW-форм-urlencoded

Теперь измените enctype на application/x-www-form-urlencoded, перезагрузите браузер и повторите отправку.

Firefox отправил:

POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: application/x-www-form-urlencoded
Content-Length: 51

text1=text+default&text2=a%CF%89b&file1=a.txt&file2=a.html&file3=binary

Понятно, что данные файла не были отправлены, только базовые имена. Так что это не может быть использовано для файлов.

Что касается текстового поля, мы видим, что обычные печатаемые символы, такие как a и b отправлялись одним байтом, тогда как непечатаемые символы, такие как 0xCF и 0x89 занимали 3 байта каждый: %CF%89 !

сравнение

Загрузки файлов часто содержат много непечатаемых символов (например, изображений), в то время как текстовые формы почти никогда не используются.

Из примеров мы видели, что:

  • multipart/form-data: добавляет к сообщению несколько байтов служебных данных границы и должен потратить некоторое время на его вычисление, но отправляет каждый байт в одном байте.

  • application/x-www-form-urlencoded: имеет одну байтовую границу для каждого поля (&), но добавляет линейный коэффициент издержек 3x для каждого непечатаемого символа.

Поэтому, даже если бы мы могли отправлять файлы с application/x-www-form-urlencoded, мы бы этого не хотели, потому что это неэффективно.

Но для печатных символов, найденных в текстовых полях, это не имеет значения и создает меньше накладных расходов, поэтому мы просто используем их.

Ответ 3

enctype='multipart/form-data - это тип кодирования, который позволяет отправлять файлы через POST. Совершенно просто, без этой кодировки файлы не могут быть отправлены через POST.

Если вы хотите разрешить пользователю загружать файл через форму, вы должны использовать этот enctype.

Ответ 4

При отправке формы вы указываете браузеру отправлять по протоколу HTTP сообщение в сети, надлежащим образом заключенное в структуру сообщения протокола TCP/IP. На странице HTML есть способ отправки данных на сервер: с помощью <form> s.

При отправке формы, HTTP-запроса, если он создан и отправлен на сервер, сообщение будет содержать имена полей в форме и значения, заполненные пользователем. Эта передача может происходить с помощью методов POST или GET HTTP.

  • POST сообщает вашему браузеру, что нужно создать HTTP-сообщение и поместить все содержимое в тело сообщения (очень полезный способ сделать что-то более безопасное и гибкое).
  • GET отправит данные формы в строке запроса. У этого есть некоторые ограничения относительно представления данных и длины.

Заявление о том, как отправить вашу форму на сервер

Атрибут enctype имеет смысл только при использовании метода POST. Когда он указан, он указывает браузеру отправлять форму, кодируя ее содержимое определенным образом. От MDN - Форма энктипа:

Если значение атрибута метода - post, enctype - это тип содержимого MIME, который используется для отправки формы на сервер.

  • application/x-www-form-urlencoded: это значение по умолчанию. Когда форма отправляется, все имена и значения собираются, и в последней строке выполняется кодировка URL.
  • multipart/form-data: символы НЕ кодируются. Это важно, когда форма имеет элемент управления загрузкой файлов. Вы хотите отправить двоичный файл, и это гарантирует, что поток битов не будет изменен.
  • text/plain: пробелы преобразуются, но кодирование больше не выполняется.

Безопасность

При отправке форм могут возникать некоторые проблемы безопасности, как указано в Разделе 7 RFC 7578: Данные из нескольких частей - Вопросы безопасности:

Все программное обеспечение для обработки форм должно обрабатывать предоставленные пользователем данные формы
с чувствительностью, поскольку это часто содержит конфиденциально или лично
идентифицирующая информация. В веб-браузерах широко используются функции автозаполнения форм; они могут быть использованы, чтобы обмануть пользователей
неосознанно отправлять конфиденциальную информацию при заполнении в противном случае
безобидные задачи. multipart/form-data не предоставляет никаких функций
для проверки целостности, обеспечения конфиденциальности, избегая пользователя
путаница или другие функции безопасности; эти проблемы должны быть
адресованные приложениями для заполнения форм и интерпретации данных форм.

Приложения, которые получают формы и обрабатывают их, должны быть осторожны, чтобы не возвращать данные запрашивающему сайту обработки форм, который не предназначался для отправки.

Это важно при интерпретации имени файла Content-
Поле заголовка расположения, чтобы случайно не перезаписать файлы в
файловое пространство получателя.

Это касается вас, если вы разработчик, и ваш сервер будет обрабатывать формы, отправленные пользователями, которые могут в конечном итоге содержать конфиденциальную информацию.

Ответ 5

enctype='multipart/form-data' означает, что никакие символы не будут закодированы. поэтому этот тип используется при загрузке файлов на сервер.
Таким образом, multipart/form-data используется, когда форма требует, чтобы бинарные данные, такие как содержимое файла, загружались

Ответ 6

Установите атрибут метода POST, потому что содержимое файла не может быть помещено в параметр URL с помощью формы.

Задайте значение enctype для multipart/form-data, поскольку данные будут разбиты на несколько частей, по одному для каждого файла плюс один для текста тела формы, который может быть отправлен с ними.

Ответ 7

Обычно это когда у вас есть форма POST, которая должна загружать файл как данные... это скажет серверу, как он будет кодировать переданные данные, в таком случае он не будет закодирован, потому что он будет просто передавать и загружать файлы на сервер, например, при загрузке изображения или pdf

Ответ 8

  • Атрибут enctype (ENC ode TYPE) указывает, как данные формы должны быть закодированы при отправке их на сервер.
  • multipart/form-data - это одно из значений атрибута enctype, которое используется в элементе формы, в который загружается файл. multi-part означает, что данные формы разделяются на несколько частей и отправляются на сервер.

Ответ 9

Атрибут enctype указывает, как данные формы должны быть закодированы при отправке на сервер.

Атрибут enctype можно использовать только если method = "post".

Никакие символы не закодированы. Это значение требуется при использовании форм, которые имеют элемент управления загрузкой файлов

Из W3Schools