Какова граница в multipart / form-data?

403

Я хочу задать вопрос о multipart/form-data. В заголовке HTTP я обнаружил, что Content-Type: multipart/form-data; boundary=???.

Является ли ???свободный быть определенным пользователем? Или это сгенерировано из HTML? Можно ли мне определить ??? = abcdefg?

Вопросов
источник
2
Я нашел это ответ. w3.org/TR/html401/interact/forms.html#h-17.13.4.2
Вопросы

Ответы:

424

Является ли ???свободный быть определенным пользователем?

Да.

или это предоставляется HTML?

Нет. HTML не имеет к этому никакого отношения . Читай ниже.

Можно ли для меня определить ???как abcdefg?

Да.

Если вы хотите отправить следующие данные на веб-сервер:

name = John
age = 12

использование application/x-www-form-urlencodedбудет выглядеть так:

name=John&age=12

Как видите, сервер знает, что параметры разделены амперсандом &. Если& для значения параметра требуется, то оно должно быть закодировано.

Так как же сервер узнает, где начинается и заканчивается значение параметра, когда он получает HTTP-запрос, используя multipart/form-data?

Используя границу , похожую на &.

Например:

--XXX
Content-Disposition: form-data; name="name"

John
--XXX
Content-Disposition: form-data; name="age"

12
--XXX--

В этом случае граничное значение равно XXX. Вы указываете это в Content-Typeзаголовке, чтобы сервер знал, как разделить полученные данные.

Так что вам нужно:

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

  • Будьте последовательны и используйте одно и то же значение везде в сообщении запроса.

Оскар Медерос
источник
54
Вы должны добавить дополнительные «-» в конце границы.
Себастьян Пискорский
13
Вы можете прочитать это в документации. Конец границы должен иметь два дополнительных гипса »-« Ссылка: w3.org/TR/html401/interact/forms.html#h-17.13.4.2
Себастьян Пискорский
6
Отличный ответ. Граница - это просто «ключ» для разделения нескольких «частей» полезной нагрузки, состоящей из нескольких частей. Обычно что-то вроде '&' достаточно для разделения переменных, но вам нужно нечто более уникальное для разделения полезных нагрузок внутри полезной нагрузки.
user2483724
1
@ K3rnel31 Конечно, если новая граничная строка не имеет такую ​​же длину.
Оскар Медерос
5
Я думаю, что граничное значение, как объявлено в заголовке Content-Type, на самом деле будет -XXX --- потому что при разделении частей должен быть написан дополнительный «-» (отсюда --- XXX ---)
Theodore K .
96

Точный ответ на вопрос: да, вы можете использовать произвольное значение для boundaryпараметра , если оно не превышает 70 байт и состоит только из 7-битныхUS-ASCII (печатаемых) символов.

Если вы используете один из multipart/*типов контента, вам действительно необходимо указать boundaryпараметр в Content-Typeзаголовке, иначе сервер (в случае HTTP-запроса) не сможет проанализировать полезную нагрузку.

Вы, вероятно, также хотите установить charset параметр UTF-8в своем Content-Typeзаголовке, если только вы не можете быть абсолютно уверены, что US-ASCIIв данных полезной нагрузки будет использоваться только кодировка.

Несколько соответствующих выдержек из RFC2046 :

  • 4.1.2. Параметр Charset:

    В отличие от некоторых других значений параметров, значения параметра charset НЕ чувствительны к регистру. Набор символов по умолчанию, который должен приниматься при отсутствии параметра charset, - US-ASCII.

  • 5.1. Multipart Media Type

    Как указано в определении поля Content-Transfer-Encoding [RFC 2045], для объектов типа «multipart» не допускается никакая другая кодировка, кроме «7-битная», «8-битная» или «двоичная». «Составные» граничные разделители и поля заголовка всегда представлены как 7-битный US-ASCII в любом случае (хотя поля заголовка могут кодировать текст заголовка не-US-ASCII в соответствии с RFC 2047), а данные внутри частей тела могут быть закодированы на по частям, с полями Content-Transfer-Encoding для каждой подходящей части тела.

    Поле Content-Type для составных объектов требует один параметр, "border". Строка ограничителя границы затем определяется как строка, состоящая полностью из двух символов дефиса ("-", десятичное значение 45), за которыми следует значение параметра границы из поля заголовка Content-Type, необязательный линейный пробел и завершающий CRLF.

    Ограничители границ не должны появляться внутри инкапсулированного материала и должны содержать не более 70 символов, не считая двух ведущих дефисов.

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

Вот пример использования произвольной границы:

Content-Type: multipart/form-data; charset=utf-8; boundary="another cool boundary"

--another cool boundary
Content-Disposition: form-data; name="foo"

bar
--another cool boundary
Content-Disposition: form-data; name="baz"

quux
--another cool boundary--
antichris
источник
2
Мне больше нравится этот ответ, потому что он цитирует RFC о том, как определены дефисы .
Рик
@Rick Там есть веская причина для IETF , чтобы сделать это - хотя все они выглядят почти так же , только один из следующих четырех является правильным символ дефиса: ˗ - - -
antichris
ха, когда я сказал, что гипс, я имею в виду, что ваш ответ сказал мне, какие гипс определены в стандарте. Я был озадачен тем, какие ипотеки «определены клиентом», а какие «определены спецификацией»
Рик
31

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

Форма с атрибутом enctype = "multipart / form-data" будет иметь заголовок запроса Content-Type: multipart / form-data; border --- WebKit193844043-h ( сгенерированный браузером vaue ).

Переданная полезная нагрузка выглядит примерно так:

Content-Type: multipart/form-data; boundary=---WebKitFormBoundary7MA4YWxkTrZu0gW

    -----WebKitFormBoundary7MA4YWxkTrZu0gW
    Content-Disposition: form-data; name=”file”; filename=”captcha
    Content-Type:

    -----WebKitFormBoundary7MA4YWxkTrZu0gW
    Content-Disposition: form-data; name=”action

    submit
    -----WebKitFormBoundary7MA4YWxkTrZu0gW--

Со стороны веб-сервиса, он используется в форме @Consumes ("multipart / form-data").

Помните, что при тестировании вашего веб-сервиса с помощью Chrome Postman вам необходимо проверить опцию данных формы (переключатель) и меню «Файл» из выпадающего списка, чтобы отправить вложение. Явное предоставление типа содержимого как multipart / form-data приводит к ошибке. Потому что граница отсутствует, поскольку она переопределяет запрос curl почтового человека на сервер с типом контента, добавляя границу, которая работает нормально.

См. RFC1341 sec7.2 Multipart Content-Type.

Yergalem
источник