Что означает enctype = 'multipart / form-data'? - PullRequest
1210 голосов
/ 24 декабря 2010

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

Ответы [ 9 ]

1370 голосов
/ 24 декабря 2010

Когда вы делаете запрос 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 и полезен только для отладки - из спецификации : Они не могут быть надежно интерпретированы компьютером - и я бы сказал, что остальные в сочетании с инструментами (например, вкладка «Сеть» в инструментах разработчика большинства браузеров) для этого лучше).

382 голосов

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

Правильный ответ Квентина: используйте 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.

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 на 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: имеет одну байтовую границу на поле (&), но добавляет linear коэффициент издержек 3x для каждого непечатаемого символа.

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

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

83 голосов
/ 24 декабря 2010

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

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

73 голосов
/ 24 декабря 2010

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

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

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

Указание того, как отправить форму на сервер

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

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

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

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

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

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

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

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

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

32 голосов
/ 04 июля 2013

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

8 голосов
/ 25 сентября 2013

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

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

0 голосов
/ 12 ноября 2018

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

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

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

Из W3Schools

0 голосов
/ 10 марта 2016

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

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