Что означает enctype='multipart/form-data'?
Что значит enctype='multipart/form-data'
имела в виду HTML
форма и когда мы должны использовать его?
8 ответов
когда вы делаете запрос POST, вы должны каким-то образом кодировать данные, которые образуют тело запроса.
HTML-формы предоставляют три метода кодирования.
-
application/x-www-form-urlencoded
(по умолчанию) multipart/form-data
text/plain
работа над добавлением application/json
, но это было оставлено.
специфика форматов не имеет значения для большинства разработчиков. Этот важными моментами являются:
когда вы пишете код на стороне клиента, все, что вам нужно знать использовать multipart/form-data
когда ваша форма включает любые <input type="file">
элементов.
когда вы пишете серверный код: использовать заготовки форма обработки библиотека (например, Perl CGI->param
или тот, который подвергается PHP $_POST
superglobal), и он позаботится о различиях для вас. Не пытайтесь анализировать необработанные входные данные, полученные сервер.
никогда не используйте text/plain
.
если вы пишете (или отлаживаете) библиотеку для анализа или генерации необработанных данных, вам нужно начать беспокоиться о формате. Вы также можете узнать об этом ради интереса.
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
(spec указывает на RFC7578) -
text-plain
. Это "не надежно интерпретируется компьютером", поэтому его никогда не следует использовать в производстве, и мы не будем углубляться в него.
как генерировать примеры
как только вы видите пример каждого метода, это становится очевидным как они работают, и когда нужно использовать каждый из них.
вы можете привести примеры, используя:
-
nc -l
или эхо-сервер:тестовый сервер HTTP, принимающий запросы GET / POST - пользовательский агент, такой как браузер или cURL
сохранить форму до минимума :
<!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.
multipart/form-data
в 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
= = 'a' и 62
= = 'b').
поэтому ясно, что:
Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266
задает тип содержимогоmultipart/form-data
и говорит, что поля разделены с учетомboundary
строку.-
каждое поле получает некоторые подзаголовки перед его данными:
Content-Disposition: form-data;
, поле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-sequences -
Content-Type
автоматически определяется браузером.как именно определяется был задан вопрос:как тип MIME файла определяется браузер?
application / x-www-form-urlencoded
изменить enctype
to 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
- Это тип кодировки, который позволяет отправлять файлы через в должности. Проще говоря, без этой кодировки файлы не могут быть отправлены через в должности.
Если вы хотите позволить пользователю загрузить файл через форму, вы должны использовать enctype.
при отправке формы вы пытаетесь сказать, что ваш браузер отправляет по протоколу HTTP сообщение в сети, правильно обернутое в структуру сообщений протокола TCP/IP. При отправке данных, вы можете использовать POST
или GET
методы для отправки данных по протоколу HTTP. POST
говорит вашему браузеру создать HTTP-сообщение и поместить все содержимое в тело сообщения (очень полезный способ делать вещи, более безопасным, а также гибким). GET
имеет некоторые ограничения в отношении данных представление и длина.
о том, что вы посылаете
при отправке файла необходимо сообщить протоколу HTTP, что вы отправляете файл, имеющий несколько характеристик и информацию внутри него. Таким образом, можно последовательно отправлять данные в приемник и позволить ему открыть файл с текущим форматом и так далее... Это требование из протокола HTTP, как показано здесь
вы не можете отправлять файлы по умолчанию enctype
параметры, потому что ваш приемник может столкнуться с проблемами, читая его (подумайте, что файл является дескриптором для некоторых данных для конкретной операционной системы, если вы видите вещи таким образом, возможно, вы поймете, почему так важно указать другой enctype
для файлов).
не забывайте о безопасности!--12-->
этот способ делать вещи также гарантирует, что некоторые алгоритмы безопасности работают на ваших сообщениях. Эта информация также используется маршрутизаторами уровня приложения в чтобы действовать как хорошие брандмауэры для внешних данных.
Ну, как вы можете видеть, это не глупо, используя конкретный enctype
для файлов.
enctype='multipart/form-data'
означает, что символы будут закодированы. именно поэтому этот тип используется при загрузке файлов на сервер.
Так что multipart/form-data
используется, когда форма требует двоичных данных, таких как содержимое файла, для загрузки
установите атрибут метода в POST, потому что содержимое файла не может быть помещено в параметр URL с помощью формы.
установите значение enctype в multipart / form-data, потому что данные будут разделены на несколько частей, по одной для каждого файла плюс один для текста тела формы, который может быть отправлен с ними.
- enctype(ENCода тип) атрибут указывает, как данные формы должны быть закодированы при отправке на сервер.
-
multipart / form-data является одним из значений атрибута enctype, который используется в элементе формы, который имеет загрузку файла. многосерийный означает, что данные формы делятся на нескольких частей и отправить на сервер.
- метафора часть: документ HTML имеет из двух частей: голова и тело.
обычно это когда у вас есть форма POST, которая должна принимать загрузку файла в качестве данных... это скажет серверу, как он будет кодировать передаваемые данные, в таком случае он не будет кодироваться, потому что он будет просто передавать и загружать файлы на сервер, например, при загрузке изображения или pdf