Есть ли практическая разница между запросом/ответом HTTP с пустым телом и запросом/ответом без тела? Различается ли какая-либо версия спецификации HTTP между ними или они эквивалентны?
Я думаю, было бы также полезно определить разницу между этими двумя случаями. Насколько я понимаю, пустое тело имеет заголовок Content-Type, а отсутствующее тело — нет. Не стесняйтесь поправить меня, если я ошибаюсь.





Да, пустое тело может иметь (а может и не иметь) заголовок Content-Type. Их можно обрабатывать одинаково или по-разному в зависимости от приложения, которому вы отправляете запросы.
Пустое тело все еще могло служить нескольким целям. Представьте себе опрос, в котором все поля являются необязательными. Пустое тело будет указывать на то, что человек намеренно решил оставить их все пустыми, и владелец приложения может, например, пометить все эти поля как «Пользователь предпочел бы не отвечать», игнорируя при этом отсутствующие тела ответа.
Еще одно полезное следствие для этого же случая (опрос необязательных полей) заключается в том, что даже если у вас будет пустое тело, любой, у кого есть доступ к POST-запросу, сможет увидеть, что он был закодирован как application/x-www-form-urlencoded, поэтому даже с пустым запросе понятно, какие данные предполагается получить по заполненной форме, где отсутствующий орган не дал бы такую информацию.
Заголовок Content-Type не имеет никакого отношения к тому, присутствует ли тело сообщения. Он просто сообщает вам, каков тип данных тела, если тело присутствует.
Пустое тело обозначается заголовком Content-Length: 0 или заголовком Transfer-Encoding: chunked, где тело состоит только из фрагмента нулевого размера. Это отличается от ситуации, когда тела вообще нет.
RFC 2616, раздел 4.3 и RFC 7230, раздел 3.3 объясняют, как узнать, действительно ли присутствует тело сообщения или нет.
RFC 2616:
The rules for when a message-body is allowed in a message differ for
requests and responses.
The presence of a message-body in a request is signaled by the
inclusion of a Content-Length or Transfer-Encoding header field in
the request's message-headers. A message-body MUST NOT be included in
a request if the specification of the request method (section 5.1.1)
does not allow sending an entity-body in requests. A server SHOULD
read and forward a message-body on any request; if the request method
does not include defined semantics for an entity-body, then the
message-body SHOULD be ignored when handling the request.
For response messages, whether or not a message-body is included with
a message is dependent on both the request method and the response
status code (section 6.1.1). All responses to the HEAD request method
MUST NOT include a message-body, even though the presence of entity-
header fields might lead one to believe they do. All 1xx
(informational), 204 (no content), and 304 (not modified) responses
MUST NOT include a message-body. All other responses do include a
message-body, although it MAY be of zero length.
RFC 7230:
The rules for when a message body is allowed in a message differ for
requests and responses.
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.
The presence of a message body in a response depends on both the
request method to which it is responding and the response status code
(Section 3.1.2). Responses to the HEAD request method (Section 4.3.2
of [RFC7231]) never include a message body because the associated
response header fields (e.g., Transfer-Encoding, Content-Length,
etc.), if present, indicate only what their values would have been if
the request method had been GET (Section 4.3.1 of [RFC7231]). 2xx
(Successful) responses to a CONNECT request method (Section 4.3.6 of
[RFC7231]) switch to tunnel mode instead of having a message body.
All 1xx (Informational), 204 (No Content), and 304 (Not Modified)
responses do not include a message body. All other responses do
include a message body, although the body might be of zero length.
Спасибо за полезный ответ, но это ответ только на половину вопроса. Делает ли спецификация различие между отсутствующим телом и пустым телом?
Почему цитаты в моем ответе не отвечают вам на этот вопрос? Это явно различает.
Извините, вы правы, что мой вопрос не задавал этого явно... Хотя спецификация позволяет нам различать эти два случая, указывает ли она, можно ли использовать их как взаимозаменяемые? Например, ответ HTTP 204 («Нет контента») не должен иметь тела. Ничего, если вместо этого будет возвращено пустое тело? HTTP GET не должен иметь тела запроса. Ничего, если вместо этого будет возвращено пустое тело? Судя по всему, ответ — нет. Вы согласны?
В большинстве случаев они взаимозаменяемы, за исключением случаев, когда это не так. Например, «Метод HEAD идентичен GET, за исключением того, что сервер НЕ ДОЛЖЕН возвращать тело сообщения в ответе» и «Ответ 204 НЕ ДОЛЖЕН включать тело сообщения» и т. д. Тело GET является весьма спорным, RFC не разъясняют это. Фактически, Раздел 4.3.1 RFC 7231 прямо говорит: «Полезная нагрузка в сообщении запроса GET не имеет определенной семантики; отправка тела полезной нагрузки в запросе GET может привести к тому, что некоторые существующие реализации отклонят запрос».
Я понимаю эту точку зрения, но действительно ли спецификация HTTP подтверждает эту интерпретацию (что пустое тело не эквивалентно отсутствию тела)?