← Все вопросы

СреднеJuniorBackendDevOps
В чём основные различия между методами HTTP-запросов GET и POST?
Коротко
GET запрашивает данные (только чтение), безопасен, идемпотентен и кэшируется
по умолчанию; параметры передаются в URL. POST отправляет данные в теле запроса
для обработки на сервере и по умолчанию не является безопасным, идемпотентным
или кэшируемым.
Назначение
- GET запрашивает представление ресурса. По спецификации это операция только для чтения: клиент не ожидает изменения состояния сервера. Согласно RFC 9110, отправка тела в GET-запросе имеет неопределённую семантику, поэтому тело использовать не следует.
- POST просит целевой ресурс обработать данные из тела запроса согласно собственной логике этого ресурса (создание записи, отправка формы, загрузка файла и т. п.).
Где находятся данные
- GET передаёт параметры в строке URL (query string после
?, форматkey=value&...). Они видны в адресной строке, попадают в логи и историю браузера, ограничены практическим лимитом длины URL. - POST передаёт данные в теле запроса; тип указывается заголовком
Content-Type. HTML-формы обычно используютapplication/x-www-form-urlencoded(по умолчанию) илиmultipart/form-data(для файлов). Жёсткого лимита на уровне протокола нет, но серверы и прокси задают собственные максимумы (например,client_max_body_sizeв Nginx).
Свойства по RFC 9110
- Безопасность (safe): GET безопасен (только чтение), POST — нет.
- Идемпотентность: запрос идемпотентен, если N одинаковых запросов оказывают на состояние сервера тот же эффект, что и один. GET идемпотентен, POST — нет: повтор может создать дубликаты (например, два одинаковых заказа). Идемпотентность не равна безопасности (PUT и DELETE идемпотентны, но не безопасны) и ничего не говорит об идентичности тела ответа.
- Кэшируемость: ответы GET кэшируются по умолчанию; ответы POST — только при явной актуальности (freshness) и заголовке
Content-Location, что на практике редко.
Практические следствия
- GET используют для получения и навигации; результат можно безопасно повторять, сохранять в закладки и предзагружать. Обновление GET-страницы безвредно.
- POST применяют для изменяющих состояние действий и для передачи конфиденциальных или больших данных. Обновление или возврат назад на POST-странице вызывает предупреждение браузера о повторной отправке формы.
- Передавать пароли через GET нельзя: они окажутся в URL, логах и истории. Это вопрос гигиены, а не шифрования — HTTPS шифрует и URL, и тело, но URL всё равно логируется.
Частые уточнения
- Безопасны GET, HEAD, OPTIONS; идемпотентны GET, HEAD, PUT, DELETE; POST — ни то, ни другое.
- Оба метода поддерживаются HTML-формами (атрибут
method). - «Безопасность» в смысле RFC означает отсутствие изменения состояния, а не защиту данных.
- Идемпотентность POST на уровне приложения часто обеспечивают ключами идемпотентности.