Какой способ кодирования данных формы enctype нужно использовать если в форме отправляется файл

Обновлено: 07.07.2024

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

Когда вы делаете запрос POST, вы должны кодировать данные, которые каким-то образом формируют тело запроса.

HTML-формы предоставляют три метода кодирования.

  • application/x-www-form-urlencoded (по умолчанию) multipart/form-data литий> text/plain литий>

Ведется работа по добавлению application/json , но это было заброшено.

Специфика форматов не имеет значения для большинства разработчиков. Важные моменты:

Когда вы пишете код на стороне клиента, вам нужно только использовать multipart/form-data , если ваша форма содержит ---- +: = 5 =: + ---- elements .

Когда вы пишете код на стороне сервера: Используйте предварительно написанную библиотеку обработки форм (например, Perl <input type="file"> или тот, который представлен в PHP CGI->param superglobal), и он позаботится о различиях для вас. Не пытайтесь анализировать необработанные данные, полученные сервером.

Никогда не используйте $_POST .

Если вы пишете (или отлаживаете) библиотеку для анализа или генерации необработанных данных, вам нужно начать беспокоиться о формате. Вы также можете узнать об этом ради интереса.

text/plain более или менее совпадает со строкой запроса в конце URL-адреса.

application/x-www-form-urlencoded значительно сложнее, но позволяет включать в данные целые файлы. Пример результата можно найти в спецификации HTML 4. .

multipart/form-data представлен HTML 5 и полезен только для отладки - из спецификации : они не могут быть надежно интерпретированы компьютером - и я ' буду утверждать, что другие в сочетании с инструментами (например, вкладка «Сеть» в инструментах разработчика большинства браузеров) лучше для этого).

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

Ответ Квентина правильный: используйте multipart/form-data , если форма содержит загружаемый файл, и application/x-www-form-urlencoded в противном случае, который используется по умолчанию, если вы пропустите enctype .

  • добавьте еще несколько ссылок на HTML5
  • объясните почему он прав с примером отправки формы

HTML5 ссылки

Существует три возможности для enctype :

  • x-www-urlencoded
  • multipart/form-data (спецификация указывает на RFC7578 )
  • text-plain . Это «ненадежно интерпретируется компьютером», поэтому никогда не должно использоваться в производстве, и мы не будем вдаваться в подробности.

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

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

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

Сохраните форму в минимальном .html файле:

Создание файлов для загрузки:

Запустите наш маленький эхо-сервер:

nc печатает полученный запрос.

Проверено на: Ubuntu 14.04.3, nc BSD 1.105, Firefox 40.

многочастная /форма-данные

Для двоичного файла и текстового поля байты 61 CF 89 62 ( aωb в UTF-8) отправляются буквально. Вы можете проверить это с помощью nc -l localhost 8000 | hd , который говорит, что байты:

были отправлены ( 61 == 'a' и 62 == 'b').

Поэтому ясно, что:

Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266 устанавливает тип контента в multipart/form-data и говорит, что поля разделены заданной строкой boundary .

каждое поле получает несколько подзаголовков перед своими данными: Content-Disposition: form-data; , поле name , filename , за которыми следуют данные.

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

Поскольку у нас есть уникальная граница, кодирование данных не требуется: двоичные данные отправляются как есть.

Content-Type автоматически определяется браузером.

Как это точно определяется, было задано по адресу: "> Как браузер определяет тип mime загруженного файла?

применение /х-WWW-форм-urlencoded

Теперь измените enctype на application/x-www-form-urlencoded , перезагрузите браузер и повторите отправку.

Очевидно, данные файла не были отправлены, только базовые имена. Так что это не может быть использовано для файлов.

Что касается текстового поля, мы видим, что обычные печатные символы, такие как a и b были отправлены в один байт, а непечатные, такие как 0xCF и 0x89 занимает 3 байта каждый: %CF%89

Сравнение

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

Из примеров мы видели, что:

application/x-www-form-urlencoded : имеет одну байтовую границу для каждого поля ( & ), но добавляет линейный коэффициент издержек 3x для каждого непечатаемого символа.

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

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

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

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

Заявление о том, что вы отправляете

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

Не забывайте о безопасности

Ну, как вы можете видеть, использование файлов enctype для файлов не является глупостью.

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

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

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

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

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

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

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

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

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

Куда отправляются данные?

Здесь мы обсудим, что происходит с данными при отправке формы.

О клиентской/серверной архитектуре

Примечание: Для получения более полного представления о том, как работают клиент-серверные архитектуры, ознакомьтесь с модулем «Первые шаги в программировании на стороне сервера».

На стороне клиента: определение способа отправки данных

Элемент <form> определяет способ отправки данных. Все его атрибуты предназначены для того, чтобы вы могли настроить запрос на отправку, когда пользователь нажимает кнопку отправки. Двумя наиболее важными атрибутами являются action и method .

Атрибут action

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

Здесь мы используем относительный URL - данные отправляются на другой URL на сервере:

Если атрибуты не указаны, как показано ниже, данные из формы <form> отправляются на ту же страницу, на которой размещается данная форма:

Многие старые страницы используют следующий синтаксис, чтобы указать, что данные должны быть отправлены на ту же страницу, которая содержит форму; это было необходимо, потому что до появления HTML5 атрибут action был обязательным. Это больше не нужно.

Атрибут method

Метод GET

Рассмотрим следующую форму:


Данные добавляются в URL как последовательность пар имя / значение. После того, как URL веб-адрес закончился, мы добавляем знак вопроса ( ? ), за которым следуют пары имя / значение, каждая из которых разделена амперсандом ( & ). В этом случае мы передаём две части данных на сервер:

  • say , со значением Hi
  • to , со значением Mom

Примечание: вы можете найти этот пример на GitHub — смотрите get-method.html (see it live also).

Метод POST

Давайте рассмотрим пример — это та же самая форма, которую мы рассматривали в разделе GET выше, но с атрибутом method , установленным в post .

Заголовок Content-Length указывает размер тела, а заголовок Content-Type указывает тип данных, отправляемых на сервер. Мы обсудим эти заголовки позже.

Примечание: вы можете найти этот пример на GitHub — смотрите post-method.html (see it live also).

  1. Нажмите F12
  2. Выберите Network
  3. Выберите "All"
  4. Выберите "foo.com" во вкладке "Name"
  5. Выберите "Headers"

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


Единственное, что отображается пользователю — вызываемый URL. Как упоминалось раннее, запрос с методом GET позволит пользователю увидеть информацию из запроса в URL, а запрос с методом POST не позволит. Две причины, почему это может быть важно:

На стороне сервера: получение данных

Пример: Чистый PHP


Пример: Python

Этот пример показывает, как вы можете использовать Python для решения той же задачи — отобразить отправленные данные на странице. В этом примере используется Flask framework для визуализации шаблонов, поддерживающих форму отправки данных (смотри python-example.py).

Два шаблона из коде выше взаимодействуют так:

    : Та же форма, что и выше The POST method , только с использованием action к > . (Это Jinja2 шаблон, который изначально HTML, но может содержать вызовы Python кода в фигурных скобках, которые запустятся веб-сервером. url_for('hello') буквально говорит: после отправки данных переадресуй их в /hello .) : Этот шаблон просто содержит строку, которая отображает два бита данных, переданных ему при отображении. Это сделано с помощью функции hello() , указанной выше, которая выполняется, когда запрос направляется в /hello URL.

Примечание: Опять же, этот код не будет работать, если вы просто попробуете загрузить его прямо в браузер. Python работает немного иначе, чем PHP — чтобы запустить этот код, нужно установить Python/PIP, потом установить Flask используя команду: pip3 install flask . После этого, вы сможете запустить файл из примера, используя команду: python3 python-example.py , потом открыть localhost:5000 в своём браузере.

Другие языки и фреймворки

    для Python (немного тяжеловеснее, чем Flask, но больше инструментов и опций) для Node.js для PHP для Ruby для Elixir

Стоит отметить, что использование фреймворков и работа с формами - это не всегда легко. Но это намного легче, чем пытаться написать аналогичную функциональность с нуля, и это определённо сэкономит время.

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

Особый случай: отправка файлов

Атрибут enctype

Этот атрибут позволяет конкретизировать значение в Content-Type HTTP заголовок, включённый в запрос, при генерировании отправки формы. Этот заголовок очень важен, потому что указывает серверу, какой тип данных отправляется. По умолчанию это: application/x-www-form-urlencoded . На человеческом это значит: "Это форма с данными, которые были закодированы в URL параметры."

  • Указать method атрибут POST , поскольку содержимое файла, как и сам файл, не могут быть отображены в URL параметрах.
  • Установить в enctype значение multipart/form-data , потому что данные будут разбиты на несколько частей: одна часть на файл (две части на два файла), и одна часть на текстовые данные (при условии, если форма содержит поле для получения тестовых данных).
  • Подключите один или более File picker виджетов, чтобы позволить своим пользователям выбрать, какие и сколько файлов будут загружены.

Примечание: Некоторые браузеры поддерживают multiple атрибут элемента <input> , который позволяет выбрать больше одного файла для загрузки, при использовании одного элемента <input> . То, как сервер работает с этими файлами, напрямую зависит от технологий, используемых на сервере. Как упоминалось ранее, использование фреймворков сделает вашу жизнь намного легче.

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

Проблемы безопасности

Каждый раз, когда вы отправляете данные на сервер, вы должны учитывать безопасность. HTML-формы являются наиболее распространёнными векторами атак на серверы(места, где могут происходить атаки). Проблемы вытекают не из самих форм HTML, а из-за того, как сервер обрабатывает данные из этих форм.

В зависимости от того, что вы делаете, вы можете столкнуться с некоторыми очень известными проблемами безопасности:

XSS "Межсайтовый скриптинг" и CSRF "Подделка межсайтовых запросов"

Межсайтовый скриптинг (XSS "Cross Site Request Forgery") и подделка межсайтовых запросов (CSRF "Cross-Site Scripting") - это распространённые типы атак, которые происходят при отображении данных после ответа сервера или другого пользователя.

Межсайтовый скриптинг (XSS "Cross Site Request Forgery") позволяет злоумышленникам внедрить клиентский скрипт в веб-страницы, просматриваемые другими пользователями. Подделка межсайтовых запросов (CSRF "Cross-Site Scripting") может использоваться злоумышленниками для обхода средств контроля доступа, таких как одна и та же политика происхождения. Последствие от этих атак может варьироваться от мелких неудобств до значительного риска безопасности.

CSRF-атаки аналогичны XSS-атакам в том, что они начинаются одинаково - с внедрения клиентского скрипта в веб-страницы - но их конечные цели разные. Злоумышленники CSRF пытаются назначить права пользователям с более высоким уровнем прав доступа(например, администратору сайта), чтобы выполнить действие, которое они не должны выполнять (например, отправка данных ненадёжному пользователю). Атаки XSS используют доверие пользователя к веб-сайту, в то время как атаки CSRF используют доверие веб-сайта к пользователю.

Чтобы предотвратить эти атаки, вы всегда должны проверять данные, которые пользователь отправляет на ваш сервер, и (если вам нужно отобразить их) стараться не отображать HTML-контент, предоставленный пользователем. Вместо этого вы должны обработать предоставленные пользователем данные, чтобы не отображать их слово в слово. Сегодня почти все платформы на рынке реализуют минимальный "фильтр", который удаляет элементы HTML <script> , <iframe> (en-US) и <object> (en-US) полученных от любого пользователя. Это помогает снизить риск, но не исключает его полностью.

SQL - вброс

SQL -вброс представляет собой тип атак, при которых осуществляется попытка выполнения действия с базой данных, используемой целевым веб-сайтом. В этих случаях обычно осуществляется отправка SQL-запроса в надежде, что сервер выполнит этот запрос (обычно при попытке сервера приложения сохранить данные, отправляемые пользователем). Данный вид атак является одним из самых направленных атак на веб-сайты.

Последствия могут быть ужасающими, начиная от потери данных и заканчивая утратой контроля над всей инфраструктурой веб-сайта за счёт повышения привилегий. Это очень серьёзная угроза, поэтому никогда не сохраняйте данные, отправляемые пользователем, без выполнения фильтрации данных (например, с помощью mysqli_real_escape_string() .

Такие атаки являются самыми незаметными, но при этом могут превратить ваш сервер в зомби.

Будьте параноиком: никогда не доверяйте вашим пользователям

Как вы боретесь с такими угрозами? Этот вопрос выходит далеко за рамки данной статьи, но есть несколько общих правил, которые следует всегда соблюдать. Самое важное из них - никогда не доверяйте вашим пользователям, в том числе себе; даже проверенный пользователь может быть атакован.

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

  • Избегайте потенциально опасных символов. Конкретные символы, с которыми следует соблюдать осторожность, зависят от контекста, в котором используются данные, а также от используемой платформы. Однако, все языки на стороне сервера имеют соответствующие функции для обеспечения такой защиты.
  • Ограничьте входящий объем данных для поступления только реально необходимых данных.
  • Помещайте загруженные файлы в песочницу (храните их на другом сервере и предоставляйте доступ к фалам только через отдельный поддомен или даже через совершенно другое доменное имя).

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

Примечание: В статье Безопасность веб-сайта нашего раздела серверного обучения приведено подробное обсуждение упомянутых угроз и возможных способов их устранения.

Заключение

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

Смотрите также

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

Поддержка браузерами

Спецификация

Верс. Раздел
HTML
2.0 Form: FORM Перевод
3.2 FORM
4.01 17.3 The FORM element
enctype = content-type [CI].
DTD: Transitional Strict Frameset
5.0 4.10.19.6 Form submission
The enctype and.
5.1 4.10.19.6. Form submission
The enctype and.
XHTML
1.0 Extensible HyperText Markup Language
DTD: Transitional Strict Frameset
1.1 Extensible HyperText Markup Language

Значения

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

Символы кодируемые браузером:

  • пробелы преобразуются в символы « + » ПЛЮС [U+002B];
  • символы (кроме цифр и латинских букв) преобразуются в сочетание « % » ЗНАКА ПРОЦЕНТА [U+0025] и соответствующего ASCII кода символа;
  • разрыв строки преобразуется в символы « %0D%0A ».

Данная кодировка применяется только в случаях когда данные формы передаются с помощью метода « post ».

Примечание: старайтесь использовать данную кодировку только в случаях передачи файлов.

text/plain Отправляет данные на сервер практически в незакодированном виде (кодируются только знаки перевода строки и возврата коретки). Перед отправкой данных на сервер браузер объединяет все данные формы; каждый элемент формы помещается на отдельную строку, а имя и значение элемента формы разделяются « = » ЗНАКОМ РАВНО [U+003D];

Четыре распространенных формы параметров запроса POST

Форма параметра в почтовом запросе

I. Первое знакомство с примерами почтовых запросов

1. Функция ajax в Angular

С помощью метода JSON.stringify () сервер также имеет функцию для обработки JSON.


Два, четыре распространенных метода почтового запроса:

Примечание. Атрибут enctype указывает, как данные формы должны кодироваться перед отправкой на сервер. По умолчанию данные формы будут закодированы как «application / x-www-form-urlencoded».


2. Начните знакомить с четырьмя способами:

(1)、application/x-www-form-urlencoded
Это должен быть наиболее распространенный способ отправки данных через POST. В собственной форме <form> браузера, если атрибут enctype не установлен, данные в конечном итоге будут отправлены в application / x-www-form-urlencoded.

Вы можете видеть на этом этапе,

Во-первых, Content-Type указывается как application / x-www-form-urlencoded; во-вторых, отправленные данные кодируются в соответствии с key1 = val1 & key2 = val2, и оба ключа и val транскодируются URL. Большинство серверных языков хорошо поддерживают этот метод, например, запрос ajax в jQuery,Content-Type Значения по умолчанию:「application/x-www-form-urlencoded;charset=utf-8

(2)、multipart/form-data
Это также распространенный метод почтового запроса, обычно используемый для загрузки файлов, и поддержка основных серверов также лучше. Итак, мы используем формузагрузить файлы В то время значение атрибута enctype формы <form> должно быть multipart / form-data.

Примечание. Два вышеуказанных метода: application / x-www-form-urlencoded и multipart / form-data изначально поддерживаются браузером.

(4)、text/xml

В-третьих, разница между form-data, x-www-form-urlencoded, raw и двоичным запросом post в почтальоне.


2、x-www-form-urlencoded:
эквивалентен application / x-www-from-urlencoded, который преобразует данные в форме в пары ключ-значение, например name = java & age = 23.


3、raw
Вы можете загружать текст в любом формате, вы можете загружать текст, json, xml, html и т. д.


4、binary
эквивалентен Content-Type: application / octet-stream. В буквальном смысле вы можете загружать только двоичные данные. Обычно он используется для загрузки файлов. Поскольку нет значения ключа, он может только Загрузить файл.

Разница между multipart / form-data и x-www-form-urlencoded
multipart / form-data: вы можете загружать двоичные данные, такие как файлы, или формировать пары ключ-значение, но в конце концов они будут преобразованы в часть информации;
x-www-form-urlencoded: можно загружать только пары "ключ-значение", пары "ключ-значение" разделяются.

Интеллектуальная рекомендация

совместный запрос mysql с тремя таблицами (таблица сотрудников, таблица отделов, таблица зарплат)

1. Краткое изложение проблемы: (внизу есть инструкция по созданию таблицы, копирование можно непосредственно практиковать с помощью (mysql)) Найдите отделы, в которых есть хотя бы один сотрудник. Отоб.


[Загрузчик классов обучения JVM] Третий день пользовательского контента, связанного с загрузчиком классов


IP, сеанс и cookie

Читайте также: