Что означает 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
, Это "ненадежно интерпретируется компьютером", поэтому никогда не должно использоваться в производстве, и мы не будем вдаваться в подробности.
Как генерировать примеры
Как только вы видите пример каждого метода, становится очевидно, как они работают, и когда вы должны использовать каждый из них.
Вы можете привести примеры, используя:
nc -l
или сервер ECHO: тестовый сервер HTTP, принимающий запросы GET/POST- пользовательский агент, такой как браузер или CURL
Сохраните форму до минимума .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ω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ω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-sequencesContent-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
Это значение необходимо, если пользователь будет загружать файл через форму
Пожалуйста, прочитайте это