Как параметры отправляются в запросе 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-документ, приложение должно выполнить следующие шаги:
- Прочитайте
Content-Type
поле - Если значение не является одним из поддерживаемых типов мультимедиа, вернуть ответ с
415
код состояния - в противном случае декодируйте значения из тела сообщения.
Опять же, языки вроде 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 на размер данных в количестве байтов (или символов). Мы можем использовать это, чтобы прочитать ровно столько данных из стандартного ввода.