Что означает 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. Это "не надежно интерпретируется компьютером", поэтому его никогда не следует использовать в производстве, и мы не будем углубляться в него.

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

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

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

сохранить форму до минимума :

<!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.

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