Правильно ли это утверждение? Метод HTTP GET всегда не имеет тела сообщения
Правильно ли это утверждение? Метод HTTP GET всегда не имеет тела сообщения.
Я не нашел какой-либо части RFC2616 в явном виде.
И если это не так, то в каких обстоятельствах запрос Http GET включает тело сообщения
Ответы
Ответ 1
Ни restclient, ни консоль REST поддерживают это, но curl does.
Спецификация HTTP говорит в разделе 4.3
Тело сообщения НЕ ДОЛЖНО быть включено в запрос, если спецификация метода запроса (раздел 5.1.1) не позволяет отправлять тело объекта в запросы.
Раздел 5.1.1 перенаправляет нас в раздел 9.x для различных методов. Ни один из них явно не запрещает включение тела сообщения. Однако...
Раздел 5.2 говорит
Точный ресурс, идентифицированный с помощью интернет-запроса, определяется путем изучения поля Request-URI и заголовка Host.
и в разделе 9.3 говорится
Метод GET означает получение любой информации (в форме объекта), идентифицируемой Request-URI.
Что вместе предположить, что при обработке запроса GET серверу не требуется проверять что-либо другое, чем поле заголовка Request-URI и Host.
Таким образом, спецификация HTTP не мешает вам отправлять тело сообщения с GET, но есть достаточная двусмысленность, что меня не удивит, если он не будет поддерживаться всеми серверами.
Ответ 2
Старый RFC2616 был заменен и был заменен несколькими RFC (7230-7237).
Новый RFC 7230 по HTTP/1.1 четко говорит о теле сообщения:
Тело сообщения (если есть) HTTP-сообщения используется для переноса тела полезной нагрузки этого запроса или ответа. Тело сообщения - идентичный телу полезной нагрузки, если кодирование передачи не было применяется, как описано в разделе 3.3.1.
message-body = *OCTET
Правила для того, когда тело сообщения разрешено в сообщении, различаются для запросов и ответов.
Наличие тела сообщения в запросе сигнализируется с помощью Поле заголовка Content-Length или Transfer-Encoding. Запрос сообщения
кадрирование не зависит от семантики метода, даже если метод не определять какое-либо использование для тела сообщения.
Итак, новый стандартный отчетливо отвечает на начальный вопрос. Но есть старое программное обеспечение, которое может игнорировать сообщение-тело в запросе GET, поэтому вам нужно быть осторожным и проверить этот случай.
Ответ 3
Я столкнулся с этим в elasticsearch, где для тестирования анализаторов используется запрос GET с телом сообщения - https://www.elastic.co/guide/en/elasticsearch/guide/master/analysis-intro.html
По сути, это запрос, который ничего не меняет на стороне сервера, но для передачи его требуется длинное текстовое сообщение. Похоже на использование запроса GET с телом сообщения.
Ответ 4
Я думаю, что спецификация позволяет вам добавить тело сообщения, поэтому ответ на ваш вопрос должен быть Нет (но с оговорками).
Сначала проверьте спецификацию (я цитирую RFC 7231, RFC 7232 и RFC 7234, поскольку RFC 2616, упомянутый в других ответах, был устарел ими).
Из RFC 7230:
The presence of a message body in a request is signaled by a
Content-Length or Transfer-Encoding header field. Request message
framing is independent of method semantics, even if the method does
not define any use for a message body.
Обратите внимание, что часть "Тело сообщения НЕ ДОЛЖНО быть включено в запрос, если спецификация метода запроса (раздел 5.1.1) не позволяет отправлять тело объекта в запросы". присутствующий в старом RFC 2616, был удален.
Также RFC 7231 говорит об этом по теме:
A payload within a GET request message has no defined semantics;
sending a payload body on a GET request might cause some existing
implementations to reject the request.
Итак, на мой взгляд это означает, что вы можете добавить тело сообщения в запрос GET (и это должно ответить на ваш первоначальный вопрос), но вы должны быть осторожны. Случай, упомянутый в спецификациях, - это не единственный, о котором вы должны знать, многие инструменты, клиент и сервер просто не ожидают тела сообщения и могут ошибаться. Например, в Chrome XMLHttpRequest удалит тело сообщения для GET.
Другие проблемы - это кеширование. Согласно RFC 7234.
The primary cache key consists of the request method and target URI
[...]
If a request target is subject to content negotiation, its cache
entry might consist of multiple stored responses, each differentiated
by a secondary key for the values of the original request selecting
header fields.
Это означает, что запросы с разными телами, но с одним и тем же URL (и, возможно, с выбранными заголовками), будут считаться с одинаковым ответом на кеш, даже если тело сообщения было предварительно перенаправлено на сервер.
В конце я думаю, что, если возможно, вам следует избегать использования тел сообщений в GET, если
- Вы управляете клиентом
- Вы управляете сервером
- Вы знаете о потенциальных прокси, кешах, которые могут мешать.
- Вы отключите кеширование в ответе (вы можете на самом деле иметь возможность (ab) использовать заголовки для кэширования, но я не правильно исследовал эту идею).