Правильно ли это утверждение? Метод 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) использовать заголовки для кэширования, но я не правильно исследовал эту идею).