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 состоит из трёх основных частей:
- Стартовая строка: содержит метод, URI и версию протокола.
Пример: POST /api/users HTTP/1.1
- Заголовки (headers): передают метаинформацию о запросе и теле. Обязательные заголовки:
Host— доменное имя сервера.Content-Type— формат тела запроса (например,application/json,application/x-www-form-urlencoded,multipart/form-data).Content-Length— размер тела в байтах (обязателен, если тело не пустое).
Дополнительно могут использоваться Authorization, Cookie, Accept, User-Agent и другие.
- Тело запроса (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
| Характеристика | GET | POST |
|---|---|---|
| Назначение | Получение данных | Отправка данных |
| Тело запроса | Отсутствует | Присутствует |
| Кэширование | Кэшируется браузерами и прокси | Обычно не кэшируется |
| Безопасность | Данные видны в 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 →