Как параметры отправляются в запросе HTTP POST?

В запросе HTTP GET параметры отправляются в виде строки запроса:

http://example.com/page? параметр = значение & также = другое

В запросе HTTP POST параметры не отправляются вместе с URI.

Где значения? В заголовке запроса? В теле запроса? На что это похоже?

10 ответов

Решение

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

Обычно тип контента application/x-www-form-urlencodedпоэтому тело запроса использует тот же формат, что и строка запроса:

parameter=value&also=another

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

Краткий ответ: в запросах POST значения отправляются в "теле" запроса. С веб-формами они, скорее всего, отправляются с типом медиа application/x-www-form-urlencoded или же multipart/form-data, Языки программирования или платформы, которые были разработаны для обработки веб-запросов, обычно выполняют "The Right Thing™" с такими запросами и предоставляют вам легкий доступ к легко декодируемым значениям (таким как $_REQUEST или же $_POST в PHP или cgi.FieldStorage(), flask.request.form в Python).


Теперь давайте немного отвлечемся, что может помочь понять разницу;)

Разница между GET а также POST запросы в основном семантические. Они также "используются" по-разному, что объясняет разницу в том, как значения передаются.

GET ( соответствующий раздел RFC)

При выполнении GET запрос, вы запрашиваете у сервера один или набор объектов. Чтобы позволить клиенту фильтровать результат, он может использовать так называемую "строку запроса" URL-адреса. Строка запроса является частью после ?, Это часть синтаксиса URI.

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

Обратите внимание, что ключи и значения являются частью URI. Браузеры могут наложить ограничение на длину URI. Стандарт HTTP гласит, что ограничений нет. Но на момент написания этой статьи большинство браузеров ограничивают URI (у меня нет конкретных значений). GET Запросы никогда не должны использоваться для отправки новой информации на сервер. Особенно не большие документы. Вот где вы должны использовать POST или же PUT,

POST ( соответствующий раздел RFC)

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

POST немного сложнее (и более гибким):

При получении запроса POST вы всегда должны ожидать "полезную нагрузку" или, в терминах HTTP: тело сообщения. Тело сообщения само по себе довольно бесполезно, так как нет стандартного (насколько я могу судить. Может быть, application/octet-stream?) Формата. Формат тела определяется Content-Type заголовок. При использовании HTML FORM элемент с method="POST" обычно это application/x-www-form-urlencoded, Другой очень распространенный тип - multipart / form-data, если вы используете загрузку файлов. Но это может быть что угодно, начиная от text/plain, над application/json или даже обычай application/octet-stream,

В любом случае, если POST запрос сделан с Content-Type которое не может быть обработано приложением, оно должно вернуть 415 код состояния.

Большинство языков программирования (и / или веб-фреймворков) предлагают способ де / кодирования тела сообщения из / в наиболее распространенные типы (например, application/x-www-form-urlencoded, multipart/form-data или же application/json). Так легко. Пользовательские типы потенциально требуют немного больше работы.

Используя в качестве примера стандартный кодированный HTML-документ, приложение должно выполнить следующие шаги:

  1. Прочитайте Content-Type поле
  2. Если значение не является одним из поддерживаемых типов мультимедиа, вернуть ответ с 415 код состояния
  3. в противном случае декодируйте значения из тела сообщения.

Опять же, языки вроде PHP или веб-фреймворки для других популярных языков, вероятно, справятся с этим за вас. Исключением является 415 ошибка. Никакая структура не может предсказать, какие типы контента выберет ваше приложение для поддержки и / или не поддержки. Это зависит от вас.

PUT ( соответствующий раздел RFC)

PUT запрос в значительной степени обрабатывается точно так же, как POST запрос. Большая разница в том, что POST Запрос должен позволить серверу решить, как (и если вообще нужно) создать новый ресурс. Исторически (из устаревшего RFC2616 это было создание нового ресурса в качестве "подчиненного" (дочернего) URI, куда был отправлен запрос).

PUT В отличие от этого запрос должен "депонировать" ресурс именно по этому URI и именно с этим контентом. Не больше, не меньше. Идея состоит в том, что клиент несет ответственность за создание всего ресурса перед тем, как его "положить". Сервер должен принять это как есть на данном URL.

Как следствие, POST Запрос обычно не используется для замены существующего ресурса. PUT Запрос можно сделать как создать, так и заменить.

Примечание

Есть также " параметры пути ", которые можно использовать для отправки дополнительных данных на удаленный компьютер, но они настолько необычны, что я не буду вдаваться в подробности. Но, для справки, вот выдержка из RFC:

Помимо точечных сегментов в иерархических путях, сегмент пути считается непрозрачным по общему синтаксису. Приложения, генерирующие URI, часто используют зарезервированные символы, разрешенные в сегменте, для разграничения подкомпонентов, специфичных для схемы или обработчика разыменования. Например, зарезервированные символы точки с запятой (";") и равенства ("=") часто используются для разделения параметров и значений параметров, применимых к этому сегменту. Запятая (",") зарезервированный символ часто используется для аналогичных целей. Например, один производитель URI может использовать сегмент, такой как "name;v=1.1", чтобы указать ссылку на версию 1.1 "name", тогда как другой может использовать сегмент, такой как "name, 1.1", чтобы указать то же самое. Типы параметров могут быть определены специфичной для схемы семантикой, но в большинстве случаев синтаксис параметра является специфическим для реализации алгоритма разыменования URI.

Содержимое помещается после заголовков HTTP. Формат HTTP POST должен иметь заголовки HTTP, сопровождаемые пустой строкой и телом запроса. Переменные POST хранятся в виде пар ключ-значение в теле.

Вы можете увидеть это в необработанном содержании HTTP-сообщения, показанном ниже:

POST /path/script.cgi HTTP/1.0
From: frog@jmarshall.com
User-Agent: HTTPTool/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 32

home=Cosby&favorite+flavor=flies

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

Вы не можете ввести его непосредственно в адресной строке браузера.

Например, вы можете увидеть, как данные POST отправляются в Интернете с помощью живых HTTP-заголовков. Результат будет примерно таким

http://127.0.0.1/pass.php
POST /pass.php HTTP/1.1

Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://127.0.0.1/pass.php
Cookie: passx=87e8af376bc9d9bfec2c7c0193e6af70; PHPSESSID=l9hk7mfh0ppqecg8gialak6gt5
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
username=zurfyx&pass=password

Где это говорит

Content-Length: 30
    username=zurfyx&pass=password

будут почтовые значения.

Тип носителя по умолчанию в запросе POST: application/x-www-form-urlencoded, Это формат для кодирования пар ключ-значение. Ключи могут быть дубликатами. Каждая пара ключ-значение отделяется & символ, и каждый ключ отделяется от своего значения = персонаж.

Например:

Name: John Smith
Grade: 19

Кодируется как:

Name=John+Smith&Grade=19

Это помещается в тело запроса после заголовков HTTP.

Значения форм в HTTP POST отправляются в теле запроса в том же формате, что и строка запроса.

Для получения дополнительной информации см. Спецификацию.

Некоторые из веб-сервисов требуют, чтобы вы размещали данные запроса и метаданные отдельно. Например, удаленная функция может ожидать, что подписанная строка метаданных включена в URI, а данные размещены в HTTP-теле.

Запрос POST может семантически выглядеть так:

POST /?AuthId=YOURKEY&Action=WebServiceAction&Signature=rcLXfkPldrYm04 HTTP/1.1
Content-Type: text/tab-separated-values; charset=iso-8859-1
Content-Length: []
Host: webservices.domain.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: identity
User-Agent: Mozilla/3.0 (compatible; Indy Library)

name    id
John    G12N
Sarah   J87M
Bob     N33Y

Этот подход логически объединяет QueryString и Body-Post, используя один Content-Type которая является "инструкцией по синтаксическому анализу" для веб-сервера.

Обратите внимание: HTTP / 1.1 упакован с #32 (пробел) слева и с #10 (Перевод строки) справа.

Прежде всего, давайте различать GET а также POST

Получить: это по умолчанию HTTP запрос, который сделан на сервер и используется для получения данных с сервера и строки запроса, которая идет после ? в URI используется для получения уникального ресурса.

это формат

GET /someweb.asp?data=value HTTP/1.0

Вот data=value переданное значение строки запроса

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

POST /somweb.aspHTTP/1.0
Host: localhost
Content-Type: application/x-www-form-urlencoded //you can put any format here
Content-Length: 11 //it depends
Name= somename

Почему ПОСТ над GET?

В GET значение, отправляемое на серверы, обычно добавляется к базовому URL в строке запроса. Это позволяет взломать ваши данные (это было проблемой в те дни, когда Facebook предоставлял свои учетные данные), поэтому POST используется для отправки данных на сервер, который использовал Request Body отправить ваши данные на сервер, который является более безопасным, потому что он скрывает ваши данные, плюс он получает ваши данные из полей, вычисляет их длину и добавляет их к header за content-length и никакие важные данные непосредственно не добавляются к URL

Теперь, когда ваш запрос защищен, любые значения, отправляемые на сервер, могут быть отправлены в Request Body как следует из названия, он будет содержать данные, которые пользователь хотел отправить (и он отправляется в URL Encoded формат) и Request Headers обеспечит безопасность запроса путем сравнения значений в Request Body с Request Headers

Вы можете использовать сетевой раздел Инструментов Google для разработчиков, чтобы увидеть основную информацию о том, как запросы поступают на серверы.

и вы всегда можете добавить больше значений в вашем Request Headers лайк Cache-Control, Origin, Accept,

Есть много способов / форматов параметров поста

  • formdata
  • необработанные данные
  • json
  • закодированные данные
  • файл
  • xml

Они контролируются типом содержимого в заголовке, который представлен как mime-типы.

В книге «Программирование CGI во всемирной паутине» автор говорит:

Используя метод POST, сервер отправляет данные в качестве входного потока в программу. ..... так как сервер передает информацию этой программе в виде входного потока, он устанавливает переменную среды CONTENT_LENGTH на размер данных в количестве байтов (или символов). Мы можем использовать это, чтобы прочитать ровно столько данных из стандартного ввода.

Другие вопросы по тегам