Открыть сервис

HTTP-метод POST

POST — это один из основных методов протокола HTTP (Hypertext Transfer Protocol), предназначенный для отправки данных на сервер с целью создания нового ресурса или выполнения определённого действия. В отличие от метода GET, который используется для запроса данных, POST передаёт информацию в теле запроса, что позволяет отправлять объёмные, структурированные или конфиденциальные данные. POST является идемпотентным лишь в определённых реализациях (по стандарту — не является идемпотентным), то есть повторные отправки одного и того же запроса могут привести к созданию нескольких ресурсов или к различным побочным эффектам. Метод широко применяется в веб-формах, API (REST, GraphQL, SOAP), загрузке файлов и аутентификации.

История и стандартизация

Метод POST был определён в первой спецификации HTTP/0.9 (1991 год), но тогда он не был чётко описан. В HTTP/1.0 (RFC 1945, 1996 год) POST уже был выделен как метод для отправки данных, а в HTTP/1.1 (RFC 2068, 1997 год; затем RFC 2616, 1999 год) его семантика была уточнена. В современном стандарте HTTP/1.1 (RFC 7231, 2014 год) и HTTP/2 (RFC 7540, 2015 год) метод POST сохранил свою основную роль: «запрос на обработку представления, содержащегося в запросе, для создания нового ресурса или выполнения действия». В HTTP/3 (RFC 9114, 2022 год) поддержка POST осталась без изменений, так как протокол транспортного уровня не влияет на семантику методов.

Синтаксис и структура запроса

Запрос методом POST состоит из трёх основных частей:

  1. Стартовая строка: содержит метод, URI и версию протокола.

Пример: POST /api/users HTTP/1.1

  1. Заголовки (headers): передают метаинформацию о запросе и теле. Обязательные заголовки:
  • Host — доменное имя сервера.
  • Content-Type — формат тела запроса (например, application/json, application/x-www-form-urlencoded, multipart/form-data).
  • Content-Length — размер тела в байтах (обязателен, если тело не пустое).

Дополнительно могут использоваться Authorization, Cookie, Accept, User-Agent и другие.

  1. Тело запроса (body): содержит передаваемые данные. Тело может быть пустым, если POST используется только для инициирования действия (например, для триггера на сервере). Формат тела определяется заголовком Content-Type.

Примеры запросов

Отправка формы в формате URL-encoded: ``` POST /login HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded Content-Length: 27

username=ivan&password=12345 ```

Отправка JSON-данных: ``` POST /api/orders HTTP/1.1 Host: api.example.com Content-Type: application/json Content-Length: 42

{"product":"book","quantity":2} ```

Загрузка файла (multipart/form-data): ``` POST /upload HTTP/1.1 Host: example.com Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW Content-Length: 238

------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="file"; filename="photo.jpg" Content-Type: image/jpeg

...бинарные данные... ------WebKitFormBoundary7MA4YWxkTrZu0gW-- ```

Ответ сервера

Сервер обрабатывает POST-запрос и возвращает HTTP-ответ. Коды состояния, наиболее часто используемые в ответ на POST:

  • 201 Created — ресурс успешно создан. В теле ответа обычно содержится описание нового ресурса или ссылка на него (заголовок Location).
  • 200 OK — запрос обработан, но новый ресурс не создавался (например, при выполнении действия).
  • 204 No Content — запрос обработан, но тело ответа пустое.
  • 400 Bad Request — некорректный синтаксис запроса или неверные данные.
  • 401 Unauthorized — требуется аутентификация.
  • 403 Forbidden — доступ запрещён.
  • 404 Not Found — URI не существует.
  • 409 Conflict — конфликт с текущим состоянием ресурса (например, попытка создать дубликат).
  • 422 Unprocessable Entity — данные не прошли валидацию на сервере.
  • 500 Internal Server Error — внутренняя ошибка сервера.

Свойства и отличия от других методов

Идемпотентность и безопасность

По стандарту HTTP, метод POST не является идемпотентным — повторная отправка одного и того же запроса может привести к разным результатам (например, созданию нескольких одинаковых записей). Однако на практике разработчики могут реализовать идемпотентность на стороне сервера (например, с помощью уникального ключа идемпотентности в заголовке Idempotency-Key). POST также не является безопасным (safe) — он изменяет состояние сервера.

Сравнение с GET

ХарактеристикаGETPOST
НазначениеПолучение данныхОтправка данных
Тело запросаОтсутствуетПрисутствует
КэшированиеКэшируется браузерами и проксиОбычно не кэшируется
БезопасностьДанные видны в URLДанные в теле, не видны в URL
Ограничение длиныОграничено длиной URL (обычно 2048 символов)Ограничено только настройками сервера
ИдемпотентностьДаНет (по стандарту)

Сравнение с PUT и PATCH

  • PUT — заменяет ресурс целиком, идемпотентен. POST — создаёт новый ресурс или выполняет действие.
  • PATCH — частично обновляет ресурс, не обязательно идемпотентен. POST — может использоваться для частичного обновления, но это нестандартная практика.

Применение

Веб-формы

HTML-формы с атрибутом method="post" отправляют данные на сервер. Это стандартный способ передачи логинов, паролей, текстов сообщений, файлов. Браузер автоматически кодирует данные в application/x-www-form-urlencoded или multipart/form-data (при наличии файлов).

REST API

В RESTful-архитектуре POST используется для создания новых ресурсов. Например, POST /api/users создаёт нового пользователя. Сервер возвращает статус 201 и URI созданного ресурса. POST также может применяться для выполнения действий, не подпадающих под CRUD (например, POST /api/orders/123/cancel).

GraphQL

В GraphQL все запросы (как запросы данных, так и мутации) отправляются методом POST. Тело запроса содержит JSON с полями query или mutation. Это связано с тем, что GraphQL-запросы могут быть сложными и не помещаться в URL.

SOAP

Веб-сервисы на основе SOAP используют POST для отправки XML-сообщений. Заголовок Content-Type обычно равен text/xml или application/soap+xml.

Загрузка файлов

POST позволяет передавать бинарные данные (изображения, документы, видео) в теле запроса. Для этого используется Content-Type: multipart/form-data, который разбивает данные на части (части) с собственными заголовками.

Аутентификация и авторизация

POST используется для отправки учётных данных (логин/пароль) на сервер. Например, POST /auth/login возвращает токен доступа. Также POST применяется для обновления токенов (refresh token).

Ограничения и безопасность

Размер тела

Максимальный размер POST-запроса ограничивается настройками веб-сервера (например, client_max_body_size в Nginx, maxRequestLength в ASP.NET). По умолчанию в Apache — 2 МБ, в Nginx — 1 МБ. Для загрузки больших файлов требуется изменение конфигурации.

CSRF-атаки

POST-запросы уязвимы для межсайтовой подделки запросов (Cross-Site Request Forgery). Для защиты используются CSRF-токены, которые вставляются в форму и проверяются на сервере.

Повторная отправка (duplicate submission)

Из-за неидемпотентности POST повторная отправка формы (например, при обновлении страницы) может привести к дублированию данных. Для предотвращения используются механизмы:

  • Перенаправление после POST (Post/Redirect/Get — PRG).
  • Уникальные ключи идемпотентности.
  • Проверка на стороне клиента (блокировка кнопки отправки).

Перехват данных

Данные в теле POST-запроса передаются в открытом виде (если не используется HTTPS). Для защиты конфиденциальных данных (пароли, токены) обязательно применение шифрования на транспортном уровне (TLS/SSL).

Примеры реализации на серверной стороне

PHP

``php if ($_SERVER['REQUEST_METHOD'] === 'POST') { $name = $_POST['name'] ?? ''; // обработка данных } ``

Python (Flask)

```python from flask import Flask, request app = Flask(__name__)

@app.route('/api/data', methods=['POST']) def handle_post(): data = request.get_json() return {"status": "ok"}, 201 ```

JavaScript (Node.js + Express)

```javascript const express = require('express'); const app = express();

app.post('/api/users', (req, res) => { const user = req.body; // создание пользователя res.status(201).json({ id: 1 }); }); ```

Интересные факты

  • Метод POST не имеет ограничения на длину URL, но браузеры и серверы могут ограничивать размер тела. В спецификации HTTP нет жёсткого лимита.
  • В HTTP/2 и HTTP/3 POST-запросы могут быть мультиплексированы — несколько запросов передаются по одному соединению одновременно.
  • В некоторых API POST используется для операций, которые по сути являются GET-запросами, но требуют передачи большого объёма данных (например, поиск со сложными фильтрами) — это называется «POST-запрос с телом, но без побочных эффектов» (POST для запроса данных).
  • В стандарте HTTP метод POST не гарантирует, что ресурс будет создан — он может просто инициировать процесс (например, отправку письма или запуск задачи).

Источники

  • RFC 7231 — Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content (раздел 4.3.3)
  • RFC 7540 — Hypertext Transfer Protocol Version 2 (HTTP/2)
  • RFC 9114 — Hypertext Transfer Protocol Version 3 (HTTP/3)
  • Документация MDN Web Docs: «POST» (Mozilla)
  • Спецификация HTML Living Standard — раздел «Form submission» (WHATWG)
  • Книга «HTTP: The Definitive Guide» (David Gourley, Brian Totty)

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →