Почему при загрузке файла требуется форма enctype = multipart / form-data? - PullRequest
41 голосов
/ 27 августа 2009

Почему <form enctype=multipart/form-data> требуется при загрузке файла на веб-сервер?

Ответы [ 2 ]

73 голосов
/ 27 августа 2009

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

Скотт Хансельман дает хорошее объяснение этому здесь :

HTTP и как загрузка файла работает через HTTP

Мне всегда лучше понимать ПОЧЕМУ и КАК что-то происходит. Если вы говорите «только потому, что» или «что угодно, вы просто добавляете это, и это работает», тогда я думаю, что это грустно. По какой-то причине, хотя многие люди понимают POST-формы и вообще, как данные формы передаются на сервер, при передаче файла многие просто приходят к выводу, что это волшебство. Почему мы должны добавить enctype = "multipart / form = data" в наши формы, которые включают загрузку файлов? Поскольку форма теперь будет размещена в нескольких частях.

Если у вас есть такая форма:

<form action="/home/uploadfiles" method="post" enctype="multipart/form-data">
    <label for="file">Filename:</label>
    <input type="file" name="file" id="file" />
    <input type="submit" name="submit" value="Submit" />
</form>

Полученная форма POST будет выглядеть так (слегка упрощенно):

POST /home/uploadfiles HTTP/1.1
Content-Type: multipart/form-data; boundary=---------------------------7d81b516112482 
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64)
Content-Length: 324

-----------------------------7d81b516112482 
Content-Disposition: form-data; name="file"; filename="\\SERVER\Users\Scott\test.txt"
Content-Type: text/plain

foo
-----------------------------7d81b516112482
Content-Disposition: form-data; name="submit"

Submit
-----------------------------7d81b516112482--

Обратите внимание на несколько вещей об этом POST. Во-первых, обратите внимание на content-type и border = "" и то, как позже используется граница, а именно, на границу между несколькими частями. Посмотрите, как в первой части показано, что я загрузил один файл типа text / plain. Исходя из этого, вы можете интерполировать то, как вы ожидаете, что несколько файлов будут отображаться, если все они будут размещены одновременно.

И, конечно, посмотрите, как бы это выглядело по-другому, если бы это была просто базовая форма POST без включенного enctype = "multipart / form = data":

POST /home/uploadfiles HTTP/1.1 
Content-Type: application/x-www-form-urlencoded
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64)
Content-Length: 13

submit=Submit

Видите, чем отличается тип контента? Это обычная, типичная форма POST. Возможно, нетипичным в том, что он включает только кнопку Отправить! ....

Кроме того, если вы посмотрите на свое электронное письмо с несколькими вложенными файлами, оно будет ОЧЕНЬ похоже на тело первого HTTP-сообщения, поскольку многокомпонентная кодировка MIME встречается повсеместно, как это часто бывает с большинством хороших идей.

2 голосов
/ 14 сентября 2017

Это часть спецификации для загрузки файлов HTML, как описано в RFC-1867 , которая была предложением разрешить загрузку файлов в формах HTML (около 1995 г.).

Из раздела 2:

Это предложение вносит два изменения в HTML:

1) Добавьте опцию FILE для атрибута TYPE в INPUT.
2) Разрешить атрибут ACCEPT для тега INPUT, представляющий собой список Типы носителей или шаблоны типов, разрешенные для ввода.

Кроме того, определяет новый тип носителя MIME, multipart / form-data , и определяет поведение пользовательских агентов HTML при интерпретации
форма с ENCTYPE="multipart/form-data" и / или <INPUT type="file">
теги.

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

Это позволяет браузеру отправлять несколько частей (отсюда и имя) в одном запросе и идентифицировать каждую из них своими метаданными, такими как тип mime, имя файла и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...