Можно ли передавать параметры в теле HTTP GET запроса
Что проверяют
Знаете ли вы, что «разрешено спецификацией» и «сработает по всей цепочке» это разные утверждения. Проверяют заодно кругозор: чем заменить фильтр, который не влезает в URL. Уточняют обычно, где именно такой запрос развалится.
Как отвечать
По RFC 9110 тело у GET не запрещено, но у него нет определённой семантики: сервер вправе его проигнорировать или ответить ошибкой. Отсюда вывод: отправить можно, полагаться нельзя.
- браузер:
fetchсmethod: "GET"иbodyбросаетTypeErrorещё до отправки,XMLHttpRequestтело молча выбрасывает, то есть из фронтенда так не сходить; - консольные клиенты и библиотеки:
curl -X GET -d '{...}'тело отправит,HttpClientв Java иrequestsв Python тоже; - посредники: обратные прокси, CDN и WAF могут вырезать тело, а кэш строит ключ по URL и методу, не заглядывая внутрь. Отсюда плавающие баги вида «на стенде работало, на проде отдаёт чужой ответ»;
- известное исключение: Elasticsearch и OpenSearch принимают тело в
GET /_searchи держат дубль наPOSTдля клиентов, которые так не умеют.
Откуда растёт вопрос: из длины URL. В стандарте лимита нет, ограничения у реализаций. nginx режет строку запроса по large_client_header_buffers (по умолчанию 8 КБ), IIS около 16 КБ, безопасной для любой цепочки считают величину порядка 2000 символов.
Чем заменять: POST /resource/search с телом, сохранённый фильтр по короткому идентификатору, разбиение выборки на страницы. Назовите цену размена: POST теряет кэширование на CDN и валидацию через ETag.
QA-часть: проверять не в Postman, а через реальную цепочку с балансировщиком и прокси; убедиться, что кэш не отдаёт один ответ на разные тела; помнить, что тело GET не попадает в логи доступа.
Где спотыкаются
Уверенно отвечают «нельзя, стандарт запрещает». Запрета нет, есть отсутствие гарантий, и разница тут принципиальная.
Проверяют гипотезу в Postman и делают вывод про систему целиком, минуя прокси и кэш, на которых всё и ломается.
Забывают про безопасность: параметры в URL утекают в логи, историю браузера и заголовок Referer. Это отдельный аргумент против GET с чувствительными данными.