POST (HTTP)

POST (англ. POST) — это метод запроса, поддерживаемый протоколом HTTP, используемый во Всемирной паутине. По своему назначению метод POST просит веб-сервер принять данные, содержащиеся в теле запроса, чаще всего для их хранения[1]. Метод POST часто используется для загрузки файлов или при отправке заполненной веб-формы.

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

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

Отправка данных

Всемирная паутина и протокол HTTP основаны на ряде методов запросов или «глаголов», включая POST, GET, а также PUT, DELETE и некоторые другие. Веб-браузеры, как правило, используют только GET и POST, но RESTful-веб-приложения применяют и другие методы. Назначение метода POST в линии других HTTP-методов — отправить представление новой данной сущности на сервер для её сохранения в качестве подчинённого ресурса, идентифицируемого посредством унифицированного идентификатора ресурса (URI)[1] Например, для URI http://example.com/customers POST-запросы могут служить для создания новых клиентов, каждый из которых включает свои имя, адрес, контактные данные и другие сведения. В первые годы развития интернета разработчики сайтов отошли от исходной концепции в двух основных аспектах. Во-первых, нет технической необходимости, чтобы URI содержал в явном виде указание на веб-ресурс, к которому будут сохраняться данные POST. На практике последняя часть URI чаще указывает на страницу обработки приложения и его технологию, например http://example.com/applicationform.php. Во-вторых, ввиду того, что большинство браузеров используют только GET или POST, разработчики стали применять POST для многих других задач по отправке и управлению данными, включая изменение и удаление существующих записей.

Первую проблему попытались решить некоторые влиятельные авторы уже в 1998 году[2].. Веб-фреймворки, такие как Ruby on Rails и другие, позволяют создавать для пользователей семантические адреса URL. Что касается второй проблемы, возможно использовать скриптинг на стороне клиента или самостоятельные приложения для применения других HTTP-методов, когда это необходимо[3], однако, несмотря на это, большинство веб-форм для отправки или изменения данных на сервере продолжают использовать POST для этих целей.

Это не означает, что каждая веб-форма должна указывать method="post" в своём начальном теге. Многие формы предназначены исключительно для уточнения запроса к серверу без намерения изменить основную базу данных. Например, поисковые формы оптимальны при использовании method="get"[4].

Тем не менее бывают ситуации, когда HTTP GET менее подходит даже для получения данных — например, когда требуется указать большой объём данных в URL. В браузерах и веб-серверах имеются ограничения на длину URL, которые они могут обработать без искажения или ошибки. Процентное кодирование зарезервированных знаков в URL и строках запроса может существенно увеличить их длину: Apache HTTP Server позволяет обрабатывать до 4000 символов в URL[5], а Microsoft Internet Explorer ограничен 2048 символами в URL[6]. Кроме того, HTTP GET не должен использоваться для отправки конфиденциальных данных, таких как имена пользователей и пароли. Даже при использовании HTTPS, защищающего данные от перехвата при передаче, история браузера и журналы веб-сервера, скорее всего, будут содержать полный URL в открытом виде, который может быть раскрыт при взломе одной из систем. В таких случаях рекомендуется использовать HTTP POST[7].

Применение для отправки веб-форм

Когда веб-браузер отправляет POST-запрос из элемента формы, по умолчанию используется интернет-медиа-тип «application/x-www-form-urlencoded»[8]. Это формат для кодирования пар ключ—значение, допускающий дублирование ключей. Каждая пара разделяется символом «&», а внутри пары ключ и значение — знаком «=». Ключи и значения экранируются заменой пробелов на символ «+», а все остальные неалфавитно-цифровые символы кодируются с использованием процентного кодирования[9].

Например, пары ключ—значение:

Имя: Gareth Wylie
Возраст: 24
Формула: a+b == 21

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

Name=Gareth+Wylie&Age=24&Formula=a%2Bb+%3D%3D+21

Начиная с HTML 4.0, формы могут также отправлять данные в формате multipart/form-data, определённом в RFC 2388 (см. также RFC 1867 для более ранней экспериментальной версии, представленной как расширение к HTML 2.0 и упомянутой в HTML 3.2).

Особый случай POST-запроса на ту же страницу, к которой принадлежит форма, называется обратной отправкой.

Влияние на состояние сервера

Согласно RFC 7231, метод POST не является идемпотентным, то есть повторные одинаковые запросы могут иметь отличный эффект по сравнению с единичным запросом. Поэтому POST подходит для запросов, которые изменяют состояние при каждом выполнении, например для отправки комментария к публикации в блоге или для голосования в онлайн-опросе. Метод GET считается нуллипатентным (nullipotent), без побочных эффектов, а идемпотентные операции «не имеют побочных эффектов при втором и последующих обращениях»[10][11]. По этой причине веб-краулеры, такие как поисковые роботы, обычно используют только методы GET и HEAD, чтобы их автоматические обращения не приводили к изменению данных.

Однако есть ситуации, когда POST применяется и для идемпотентных запросов — например, если запрос очень длинный. Из-за ограничений на длину URL строка запроса, генерируемая методом GET, может оказаться слишком длинной, особенно с учётом процентного кодирования[10].

Примечания

Литература