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

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

10 ответов

Решение

Когда вы делаете запрос 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's CGI->param или тот, который выставлен PHP $_POST суперглобальный) позаботится о различиях для вас. Не пытайтесь анализировать необработанные данные, полученные сервером.

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


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

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

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

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

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

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

Я собираюсь:

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

HTML5 ссылки

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

  • x-www-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, который говорит, что байты:

61 CF 89 62

были посланы (61 == 'а' и 62 == 'b').

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

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

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

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

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

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

  • 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 Мы бы не хотели, потому что это так неэффективно.

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

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

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

При отправке формы вы указываете браузеру отправлять по протоколу 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 не предоставляет никаких функций
для проверки целостности, обеспечения конфиденциальности, избегая пользователя
путаница или другие функции безопасности; эти проблемы должны быть
адресованные приложениями для заполнения форм и интерпретации данных форм.

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

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

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

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

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

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

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

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

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

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

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

Из W3Schools

Это значение необходимо, если пользователь будет загружать файл через форму

Пожалуйста, прочитайте это

https://www.w3schools.com/tags/att_form_enctype.asp

Другие вопросы по тегам