Можно ли в GET запросе отправить тело (body) и зачем
Что проверяют
Различаете ли вы «технически возможно» и «работает предсказуемо».
Как отвечать
Формально спецификация HTTP тело у запроса чтения не запрещает, но и не придаёт ему смысла: серверу разрешено его игнорировать. На практике это означает непредсказуемое поведение:
- часть прокси, балансировщиков и серверов отбрасывает тело;
- браузерный интерфейс запросов прямо запрещает тело у таких запросов, вызов завершится ошибкой;
- кэширование строится на адресе. Два запроса с одинаковым адресом и разными телами будут считаться одинаковыми, и вы получите чужой закэшированный ответ.
Поэтому практический ответ: технически иногда проходит, но полагаться на это нельзя.
Зачем вообще возникает такое желание: сложный поисковый запрос с десятком фильтров и списками значений не помещается в адрес. Ограничение на длину не стандартизовано, но серверы и прокси обычно режут где-то от двух до восьми тысяч символов, и превышение даёт ошибку о слишком длинном адресе.
Как решают правильно:
- отправка запроса методом создания на отдельный адрес поиска. Теряется кэширование и формальная идемпотентность, зато поведение предсказуемо. Так делают почти все;
- сохранённый запрос: сначала создаётся объект поиска и возвращается его идентификатор, затем результаты забираются обычным чтением по этому идентификатору. Кэширование и ссылки сохраняются, ценой лишнего обращения;
- сокращение параметров: короткие имена, кодирование набора фильтров в компактную строку.
Известное исключение стоит упомянуть: поисковый движок Elasticsearch принимает тело у запросов чтения, и именно из-за него вопрос часто и возникает.
Где спотыкаются
Утверждают, что стандарт прямо запрещает тело.
Пытаются отправить его из браузера и не понимают ошибки.
Не учитывают, что кэш смотрит только на адрес.
Не знают про ограничение длины адреса и упираются в него в проде.