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


В HTTP-протоколе ПОЛУЧИТЬ запрос, параметры отправляются как Строка запроса :

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

В HTTP-протоколе ПОСЛЕ запрос, параметры не отправляются вместе с URI.

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


1147


источник


Ответы:


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

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

parameter=value&also=another

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


940



Содержимое помещается после заголовков 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

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


343



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


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

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

ПОЛУЧИТЬ ( соответствующий раздел RFC )

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

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

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

ПОСЛЕ ( соответствующий раздел RFC )

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

POSTнемного сложнее (и путь более гибкий):

При получении запроса POST вы всегда должны ожидать «полезную нагрузку» или в терминах HTTP: тело сообщения , Тело сообщения само по себе довольно бесполезно, поскольку нет стандарт (насколько я могу судить. Возможно, формат application / octet-stream?). Формат тела определяется Content-Typeзаголовок. При использовании HTML FORMэлемент с method="POST", это обычно application/x-www-form-urlencoded, Другим очень распространенным типом является многочастному / форм-данных, если вы используете загрузку файлов. Но может быть что-нибудь , начиная от 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ошибка. Никакая структура не может предсказать, какие типы контента ваше приложение выбирает для поддержки и / или не поддержки. Это зависит от вас.

ПОЛОЖИЛ ( соответствующий раздел RFC )

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

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

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

Примечание

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

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


279



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

Вы можете видеть, как данные 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.


47



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

Например:

Name: John Smith
Grade: 19

Записывается как:

Name=John+Smith&Grade=19

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


17



Form values in HTTP POSTs are sent in the request body, in the same format as the querystring.

For more information, see the spec.


13



Some of the webservices require you to place request data and metadata separately. For example a remote function may expect that the signed metadata string is included in a URI, while the data is posted in a HTTP-body.

The POST request may semantically look like this:

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

This approach logically combines QueryString and Body-Post using a single Content-Type which is a "parsing-instruction" for a web-server.

Please note: HTTP/1.1 is wrapped with the #32 (space) on the left and with #10 (Line feed) on the right.


13