Различает ли HTTP пустое тело и отсутствие тела?

Есть ли практическая разница между запросом/ответом HTTP с пустым телом и запросом/ответом без тела? Различается ли какая-либо версия спецификации HTTP между ними или они эквивалентны?

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
159
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Да, пустое тело может иметь (а может и не иметь) заголовок Content-Type. Их можно обрабатывать одинаково или по-разному в зависимости от приложения, которому вы отправляете запросы.

Пустое тело все еще могло служить нескольким целям. Представьте себе опрос, в котором все поля являются необязательными. Пустое тело будет указывать на то, что человек намеренно решил оставить их все пустыми, и владелец приложения может, например, пометить все эти поля как «Пользователь предпочел бы не отвечать», игнорируя при этом отсутствующие тела ответа.

Еще одно полезное следствие для этого же случая (опрос необязательных полей) заключается в том, что даже если у вас будет пустое тело, любой, у кого есть доступ к POST-запросу, сможет увидеть, что он был закодирован как application/x-www-form-urlencoded, поэтому даже с пустым запросе понятно, какие данные предполагается получить по заполненной форме, где отсутствующий орган не дал бы такую ​​информацию.

Я понимаю эту точку зрения, но действительно ли спецификация HTTP подтверждает эту интерпретацию (что пустое тело не эквивалентно отсутствию тела)?

Gili 18.03.2024 23:44
Ответ принят как подходящий

Заголовок 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.

Спасибо за полезный ответ, но это ответ только на половину вопроса. Делает ли спецификация различие между отсутствующим телом и пустым телом?

Gili 18.03.2024 23:54

Почему цитаты в моем ответе не отвечают вам на этот вопрос? Это явно различает.

Remy Lebeau 19.03.2024 00:32

Извините, вы правы, что мой вопрос не задавал этого явно... Хотя спецификация позволяет нам различать эти два случая, указывает ли она, можно ли использовать их как взаимозаменяемые? Например, ответ HTTP 204 («Нет контента») не должен иметь тела. Ничего, если вместо этого будет возвращено пустое тело? HTTP GET не должен иметь тела запроса. Ничего, если вместо этого будет возвращено пустое тело? Судя по всему, ответ — нет. Вы согласны?

Gili 19.03.2024 00:49

В большинстве случаев они взаимозаменяемы, за исключением случаев, когда это не так. Например, «Метод HEAD идентичен GET, за исключением того, что сервер НЕ ДОЛЖЕН возвращать тело сообщения в ответе» и «Ответ 204 НЕ ДОЛЖЕН включать тело сообщения» и т. д. Тело GET является весьма спорным, RFC не разъясняют это. Фактически, Раздел 4.3.1 RFC 7231 прямо говорит: «Полезная нагрузка в сообщении запроса GET не имеет определенной семантики; отправка тела полезной нагрузки в запросе GET может привести к тому, что некоторые существующие реализации отклонят запрос».

Remy Lebeau 19.03.2024 00:58

Другие вопросы по теме

Завиток: (56) Ошибка приема: сброс соединения партнером | ошибка скручивания | TCP-сервер Голанга
Должен ли я ожидать, что данные http на моем http-сервере будут не в порядке для соединений, поступающих из одного клиентского сокета?
Проблемы с копированием, записью в файл, записью в буфер новой строки и объединением строки в C
Какой метод HTTP подходит для RPC через HTTP, запускающего асинхронное действие, которое в конечном итоге меняет состояние сервера?
Интеграционный тест работает для FromBody, но не для FromForm
Сообщение HTTP из NetSuite SuiteScript в конечную точку Boomi
Внутренний сервер VPS работает по протоколу http вместо https
Angular HttpInterceptor и HttpClientModule вызывают бесконечные запросы
Как я могу использовать aiohttp для получения изображения и его обработки напрямую, не сохраняя его?
Как я могу узнать или установить идентификатор для любого HTTP-запроса в Laravel