我正在为我们的应用程序开发一个新的RESTful Web服务。

当对某些实体执行GET时,客户端可以请求实体的内容。如果他们想添加一些参数(例如排序列表),可以在查询字符串中添加这些参数。

或者,我希望人们能够在请求主体中指定这些参数。HTTP/1.1似乎并没有明确禁止这一点。这将允许他们指定更多信息,可能会更容易指定复杂的XML请求。

我的问题:

这完全是个好主意吗?HTTP客户端在GET请求中使用请求体时会遇到问题吗?

https://www.rfc-editor.org/rfc/rfc2616


当前回答

根据RFC 2616第4.3节“消息正文”:

服务器应读取并转发任何请求的消息体;如果请求方法不包括实体实体的定义语义,则在处理请求时应忽略消息体。

也就是说,服务器应该始终从网络中读取任何提供的请求体(检查内容长度或读取分块体等)。此外,代理应该转发他们收到的任何此类请求。然后,如果RFC为给定方法的主体定义了语义,那么服务器实际上可以使用请求主体来生成响应。然而,如果RFC没有定义主体的语义,那么服务器应该忽略它。

这与上面Fielding的引用一致。

第9.3节“GET”描述了GET方法的语义,没有提到请求体。因此,服务器应该忽略它在GET请求中收到的任何请求体。

其他回答

如果您真的想将可计算的JSON/XML正文发送到web应用程序,那么放置数据的唯一合理位置是使用RFC4648:Base64Encoding和URL和文件名安全字母表编码的查询字符串。当然,您可以只对JSON进行URL编码,并将其放入URL参数的值中,但Base64给出的结果较小。请记住,URL大小有限制,请参阅不同浏览器中URL的最大长度是多少。

您可能会认为Base64的padding=字符可能对URL的参数值有害,但这似乎不是-请参阅以下讨论:http://mail.python.org/pipermail/python-bugs-list/2007-February/037195.html . 但是,您不应该将编码数据放在没有参数名称的位置,因为带填充的编码字符串将被解释为具有空值的参数键。我会用类似的东西_b64=<编码器数据>。

IMHO,您只需在URL中发送JSON编码(即encodeURIComponent),这样就不会违反HTTP规范并将JSON发送到服务器。

Elasticsearch接受带有主体的GET请求。甚至似乎这是首选的方法:Elasticsearch指南

一些客户端库(如Ruby驱动程序)可以在开发模式下将cry命令记录到stdout,并且它广泛使用这种语法。

虽然您可以做到这一点,但只要HTTP规范没有明确排除它,我建议避免它,因为人们不希望事情以这种方式工作。HTTP请求链中有许多阶段,虽然它们“大部分”符合HTTP规范,但唯一可以保证的是,它们的行为将与web浏览器传统使用的一样。(我想的是透明代理、加速器、A/V工具包等)

这就是稳健性原则背后的精神。大致上,“接受的内容要自由,发送的内容要保守”,你不想在没有充分理由的情况下突破规范的界限。

然而,如果你有充分的理由,那就去做吧。

根据RFC 2616第4.3节“消息正文”:

服务器应读取并转发任何请求的消息体;如果请求方法不包括实体实体的定义语义,则在处理请求时应忽略消息体。

也就是说,服务器应该始终从网络中读取任何提供的请求体(检查内容长度或读取分块体等)。此外,代理应该转发他们收到的任何此类请求。然后,如果RFC为给定方法的主体定义了语义,那么服务器实际上可以使用请求主体来生成响应。然而,如果RFC没有定义主体的语义,那么服务器应该忽略它。

这与上面Fielding的引用一致。

第9.3节“GET”描述了GET方法的语义,没有提到请求体。因此,服务器应该忽略它在GET请求中收到的任何请求体。