【问题标题】:Is an HTTP PUT request required to include a body?是否需要包含正文的 HTTP PUT 请求?
【发布时间】:2009-08-05 13:47:52
【问题描述】:

我在标准中找不到明确的规范。我有一个 HTTP 客户端,它在执行未指定正文的 PUT 请求时不包含 Content-Length: 0 标头,并且服务器被此类请求弄糊涂了,我想知道我应该责怪哪个程序。

【问题讨论】:

  • 如果我可以问,您为什么要编辑 2009 年的问题?
  • @zmuci 想要更好的格式?

标签: http


【解决方案1】:

如果 HTTP 请求具有 Content-Length 或 Transfer-Encoding 标头 (RFC 2616 4.3),则它们具有正文。如果请求两者都没有,则它没有正文,您的服务器应该这样对待它。

也就是说,PUT 请求没有正文是不寻常的,因此,如果我正在设计一个真正想要发送空正文的客户端,我会传递 Content-Length: 0。事实上,这取决于一个人的阅读在 POST 和 PUT 方法定义 (RFC 2616 9.5, 9.6) 中,有人可能会争辩说,暗示正文是必需的 - 但处理任何正文的合理方法是假定正文长度为零。

【讨论】:

  • 由于 HTTP 状态码 200(“OK”)、201(“已创建”)和 204(“无内容”)暗示,PUT 请求基本上用于在服务器。而且文件为空并没有什么非法,不是吗?
  • @bdonlan 您说带有空正文的 PUT 是不寻常的,但是如果我想启用或禁用用户,我的请求不需要正文,实际上 PUT 请求可能是“/ users/{id}/enable”或“/users/{id}/disable”。
  • @ViniciusdeAlmeida 如果您尝试遵守 REST 标准,这些资源将不合适。 disableenable 是动词。在这种情况下,我可能更愿意在/users/{id} 端点上使用PATCH
  • @crush 同意动词,但可以为 PUT "/users/{id}/enabled" 和 DELETE "/users/{id}/enabled" 提出这种情况。
【解决方案2】:

不回答问题,但断言 jaxrs 如何让我经常使用无体 PUT:

无主体放置示例: 给用户额外的权限。

PUT /admin/users/{username}/permission/{permission}

【讨论】:

  • 正是我的问题!我得出了同样的结论。但严格来说,这违反了 RFC,虽然没有明确提及,但在 RFC 中,body 被称为存在。这可能会导致问题,但根据我的经验,所有现代 Web 服务器/框架都可以工作。
  • 我的情况类似,我需要一个 API 将现有资源与用户相关联。我可以在正文中使用带有 resourceId 的 POST users/:userId/resources。或者更确切地说,它适合 PUT users/:userid/resources/:resourceId。这里最大的区别是第一个 API 应该是非幂等的,所以我可以将相同的资源与用户关联两次。 PUT 调用应该重置以前的关联
【解决方案3】:

IETF 标准不要求正文,但如果没有正文,则内容长度应为 0。使用适合您正在做的事情的方法。如果你要把它放到代码中,给定

int x;
int f(){ return x; }

还有一个名为r的远程变量。

一个帖子相当于

r=f();

一个put等价于

r=x;

get 等价于

x=r;

【讨论】:

  • 这是我读过的关于 PUT 与 POST 的最清晰的例子,虽然超出了主题
  • 如果请求有一个 Content-Length 标头,那么它就有一个正文。它可能是一个空的身体,但仍然是一个身体。与没有 Content-Length 标头的请求相比,它根本没有正文,甚至没有空的。所以是的,严格来说,PUT 请求必须有一个主体。总是。
  • 您的 POST 类比也让我完全困惑。如果我尝试继续使用您的类比,它应该更像是服务器有一个int f(int* resource, int body);,然后 POST 将调用f(&r, x);——无论服务器认为合适,这可能对r 执行或不执行.但它也可以返回东西,所以......也许更像y = f(&r, x);
【解决方案4】:

如果没有内容,什么是 PUT(动词意义上的)到服务器上? spec 将内容称为“封闭实体”,但没有内容的请求将没有封闭实体,因此没有任何东西可以放在服务器上。

当然,除非您不想在服务器上放置任何内容,在这种情况下,您可能需要 DELETE。

【讨论】:

  • 你的内容可能是 URL 编码而不是正文
  • PUT empty 只是声明具有给定身份的资源必须存在于服务器上,尽管它除了身份本身之外没有任何内容。那是与 DELETE 完全不同的语义。
  • 想象一下你想 PUT 一个资源,但接受所有服务器端的默认值。那将是 JSON 中的 Content-Length: 0{ } 作为正文?
  • 所以您的计算机上没有一个空文件,对吗?
  • “封闭实体”是否需要在正文中?
【解决方案5】:

根据 HTTP/1.1 标准 http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13 中的以下部分,内容长度字段是必需的

【讨论】:

  • 这应该不是必须的
猜你喜欢
  • 2023-02-08
  • 2011-11-11
  • 1970-01-01
  • 2022-08-15
  • 1970-01-01
  • 2019-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多