Подтвердить что ты не робот

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

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

http://example.com/page?parameter=value&also=another

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

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

4b9b3361

Ответ 1

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

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

parameter=value&also=another

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

Ответ 2

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

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

POST /path/script.cgi HTTP/1.0
From: [email protected]
User-Agent: HTTPTool/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 32

home=Cosby&favorite+flavor=flies

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

Ответ 3

Короткий ответ: в 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)

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

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

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

Side-Note

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

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

Ответ 4

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

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

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.

Ответ 5

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

Например:

Name: John Smith
Grade: 19

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

Name=John+Smith&Grade=19

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

Ответ 6

Некоторые веб-службы требуют, чтобы вы размещали данные запроса и метаданные отдельно. Например, удаленная функция может ожидать, что подписанная строка метаданных будет включена в 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 (строка) справа.

Ответ 7

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

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

Ответ 8

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

Get: Это запрос по умолчанию 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

Почему POST более GET?

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

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

теперь вопрос безопасности не совсем верен только для HTTP, данные в теле не обязательно очень безопасны, если они не зашифрованы с использованием протокола HTTP.

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

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

Ответ 9

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

Я использовал Java в качестве HTTP-клиента, чтобы показать формирование запроса GET и POST. Комментарии для описания заявления.

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * HTTP GET and POST example
 *
 * @author iampayload
 *
 */
public class GET_POST {

    private final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04";

    // GET action URL, query string appended to the URL as ?stype=models
    private final String urlGET = "https://www.servicesplus.sel.sony.com/PartsPLUSResults.aspx?stype=models";

    // POST action URL
    private final String urlPOST = "https://sg.campaign.samsung.com/smartacademy/controller/controller.php/getLocation";

    // Post data or a payload
    private String postDataBody = "state=West";

    // Main class
    public static void main(String[] args) throws Exception {

        GET_POST http = new GET_POST();

        System.out.println("Testing send HTTP GET request   HTML output is below \n");

        http.sendGET();
        System.out.println(
                "--------------------------------------------------------------------------------------------------------");

        System.out.println("Testing send HTTP POST request    HTML output is below \n");
        http.sendPost();

    }

    // HTTP POST request
    private void sendPost() throws Exception {

        // POST example URL
        URL obj = new URL(urlPOST);

        // Send post request
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        // Basic reuqest header to simulate a browser request
        con.setRequestMethod("POST");
        con.setRequestProperty("User-Agent", USER_AGENT);
        con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
        con.setRequestProperty("Upgrade-Insecure-Requests", "1");
        con.setRequestProperty("Connection", "keep-alive");
        con.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");

        // Payload
        con.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());

        // POST data added to the request as a part of body
        wr.writeBytes(postDataBody);
        wr.flush();
        wr.close();

        // Reading the HTML output of the POST HTTP request
        int responseCode = con.getResponseCode();
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        while ((inputLine = in.readLine()) != null)
            System.out.println(inputLine);
        in.close();
    }


    // HTTP GET request
    private void sendGET() throws Exception {

        URL obj = new URL(urlGET);

        // Send post request
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        // basic reuqest header to simulate a browser request
        con.setRequestMethod("GET");
        con.setRequestProperty("User-Agent", USER_AGENT);
        con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
        con.setRequestProperty("Upgrade-Insecure-Requests", "1");
        con.setRequestProperty("Connection", "keep-alive");
        con.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        con.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
        con.setDoOutput(true);

        // Reading the HTML output of the POST HTTP request
        int responseCode = con.getResponseCode();
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        while ((inputLine = in.readLine()) != null)
            System.out.println(inputLine);
        in.close();
    }
}