【问题标题】:Which HTTP methods require a body?哪些 HTTP 方法需要正文?
【发布时间】:2013-04-26 16:38:38
【问题描述】:

某些 HTTP 方法,例如 POST,需要在标头和双 CRLF 之后发送正文。

其他人,例如GET,没有正文,对他们来说,双CRLF标志着请求的结束。

但其他人呢:PUTDELETE、...如何知道哪个需要身体?

通用 HTTP 客户端应该如何响应未知的 HTTP 方法?拒绝它?默认需要body,还是默认不需要body?

我们将不胜感激。


编辑:我将详细说明我的问题,正如 cmets 中所问的那样。

我正在设计一个通用的 HTTP 客户端,程序员可以使用它向任何服务器发送任意 HTTP 请求。

客户端可以这样使用(伪代码):

HttpClient.request(method, url [, data]);

数据是可选的,可以是原始数据(字符串),也可以是键/值对的关联数组。

如果数据是一个数组,该库将对数据进行 url 编码,然后将数据附加到 URL 以用于 GET 请求,或者将其发送到消息正文以用于 POST 请求。

因此,鉴于开发人员选择的 HTTP 方法,我试图确定此 HttpClient 是否必须/应该/不得/不应在请求中包含消息正文。

【问题讨论】:

  • 通用 http 客户端 -> 通用 http 服务器。
  • @ShawnBalestracci : ?
  • 请解释您要做什么。为什么你想知道哪些方法需要一个body?你想写一个 HTTP 服务器吗?你做过any research吗?客户端也执行请求,从而确定要使用的方法;所以客户不能发出它不知道的方法。你是说服务器吗?我也不明白你为什么对何时发送尸体感到好奇。当你知道你想发送一个身体,所以如果你不知道你是否想要,你可能不应该。
  • A body is allowed for GET - 它不能改变 GET 请求的行为(所以,如果你能想到一个实际有效的用于此)
  • @CodeCaster 我不知道方法是什么,这是我正在设计的通用客户端。请查看我更新的问题。

标签: http


【解决方案1】:

编辑:编译列表:

  • entity-body 仅在存在 message-body 时才会出现(第 7.2 节)
  • message-body 的存在通过包含 Content-LengthTransfer-Encoding 标头(第 4.3 节)来表示
  • 当请求方法的规范不允许发送 entity-body 时,不得包含 message-body(第 4.3 节)
  • entity-body 仅在 TRACE 请求中被明确禁止,所有其他请求类型均不受限制(特别是第 9 节和第 9.8 节)

对于响应,已定义:

  • 是否包含 message-body 取决于请求方法响应状态(第 4.3 节)
  • 在响应 HEAD 请求时明确禁止 message-body(特别是第 9 节和第 9.4 节)
  • 在 1xx(信息性)、204(无内容)和 304(未修改)响应中明确禁止 message-body(第 4.3 节)
  • 所有其他响应都包含消息正文,尽管它的长度可能为零(第 4.3 节)

This (RFC 7231) 或 This 版本(来自 IETF 和更多深度)是您想要的。根据 RFC:

对于PUT

PUT 方法请求将封闭的实体存储在 提供的请求 URI。如果 Request-URI 引用了一个已经存在的 资源,封闭的实体应该被认为是修改过的 驻留在源服务器上的版本。如果请求 URI 不指向现有资源,并且该 URI 能够 被请求用户代理定义为新资源, 源服务器可以使用该 URI 创建资源。如果有新资源 创建后,源服务器必须通过 201 通知用户代理 (创建)响应。如果修改了现有资源,则 应该发送 200 (OK) 或 204 (No Content) 响应代码来指示 成功完成请求。如果资源不能 使用 Request-URI 创建或修改,适当的错误 应该给出反映问题性质的响应。这 实体的接收者不得忽略任何 Content-*(例如 Content-Range) 标头,它无法理解或实现,并且 在这种情况下,必须返回 501(未实施)响应。

对于DELETE

DELETE 方法请求源服务器删除资源 由 Request-URI 标识。此方法可能被人类覆盖 源服务器上的干预(或其他方式)。客户端不能 保证操作已经执行,即使 从源服务器返回的状态码表明该操作 已成功完成。但是,服务器不应该 表示成功,除非在给出响应时,它打算 删除资源或将其移动到无法访问的位置。

如果响应包含一个成功的响应应该是 200 (OK) 描述状态的实体,如果操作尚未完成,则为 202(已接受) 已制定,或 204(无内容),如果该行动已制定,但 响应不包含实体。

如果请求通过缓存并且 Request-URI 标识 一个或多个当前缓存的实体,这些条目应该被处理 作为陈旧的。对此方法的响应不可缓存。

【讨论】:

  • 我看过这个规范。但是其他任意方法呢? 默认情况下浏览器应该如何表现?
  • 它在这个 RFC 中解释了一切。 200 表示连接成功,202 表示状态被接受,204 表示没有内容。等等。
  • 我更新了我的答案以包含指向 IETF 完整规范的链接。它详细介绍了消息正文定义等。
  • 请看我对@harsh 回答的评论!
【解决方案2】:

我要回答这个问题:

  1. 从请求主体而非响应主体的角度来看,这是所要求的,也是最感兴趣的。
  2. 关于何时需要,何时禁止

没有要求要求包含正文,尽管没有正文可能被解释为空正文或零长度之一。

RFC2616 4.3 规定:

4.3 消息体 消息中何时允许消息正文的规则不同 请求和响应。

...

如果请求方法的规范(第 5.1.1 节)不允许在请求中发送实体主体,则消息主体不得包含在请求中。

浏览 5.1.1 中的方法(不包括任何扩展方法),您会发现:

9.8 跟踪

...

TRACE 请求不得包含实体。

所以技术上任何其他请求方法:

OPTIONS
GET
HEAD
POST
PUT
DELETE
CONNECT

... 可以包括一个主体。回到 4.3:

如果请求方法 不包括实体主体的定义语义,则 处理请求时应该忽略消息正文。

因此,在响应特定方法或资源的意外实体主体时,可以安全地忽略它并做出响应,包括响应代码,就好像主体没有发送一样。

参考:RFC2616 Hypertext Transfer Protocol -- HTTP/1.1

编辑: RFC2616 已经过时了,请参阅RFC7230 了解最新规范。

【讨论】:

  • rfc2616 已过时
【解决方案3】:

从您的 cmets 我了解到您正在编写一个 HTTP 客户端库(为什么,还不够?)并且您希望允许一个通用的 request(method, url[, data]) 方法。您想知道method 是必需的还是被禁止的data

假设您图书馆的用户知道他们在做什么。如果我想发送带有 GET 请求的正文,我可以,因为规范并没有禁止这样做。那么为什么你的图书馆应该呢?

此外,HTTP 规范在此开放; HTTP 的扩展(如 WebDAV)可以指定允许或不允许甚至需要消息正文的新方法(动词)。

我认为目前的努力可以更好地用于更重要的部分。

【讨论】:

  • 取决于您使用的语言,我猜。我还没有在 PHP 中找到一个正确编写的浏览器实现,用于对控制器进行功能测试(顺便说一下,使用请求/响应对象,不使用网络进行传输)。
【解决方案4】:

您可能想阅读当前 HTTP 规范草案中有关消息正文长度的部分:http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p1-messaging-22.html#message.body.length

【讨论】:

    【解决方案5】:

    对于任意方法,或您不想在服务器端支持的有效方法HTTP Status Code 405 应发送回调用方。

    根据http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

    405 Method Not Allowed 使用 该资源不支持的请求方法;[2] 例如,使用 在需要通过 POST 或使用 PUT 放在只读资源上。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 2011-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-24
      • 2012-02-20
      相关资源
      最近更新 更多