HTTP Get with 204 No Content: 这正常吗?

101
一个HTTP GET请求收到状态码为204 - No Content的响应是否是正常现象?从语义上来说,这是否符合HTTP GET应该实现的目标?我知道对于HTTP POST请求,使用204 - No Content是可以的。对于GET请求,如果没有要返回的数据,那么204状态码是否适当?我应该使用404,还是仅使用200作为成功的响应但返回一个空响应?
这个问题的用例是我正在为Google App Engine编写的Java应用程序。我向Servlet发送请求,但要发送回客户端的数据将通过Channel API socket传输而不是在HTTP响应中传输。目前,我的客户端发送一个没有请求体内容的POST请求,并等待来自Servlet的204响应,然后轮询Channel API socket。因为请求体中没有发送任何数据,所以我正在考虑是否更有意义发送GET而不是POST。

有一篇关于204状态码的相当不错的文章,请使用以下链接查找:http://blog.ploeh.dk/2013/04/30/rest-lesson-learned-avoid-204-responses/ - Aliaksei Maniuk
5个回答

114

我在使用GET/204来处理一个RESTful集合,该集合是一个已知固定长度但带空位的位置数组。

GET /items
    200: ["a", "b", null]

GET /items/0
    200: "a"

GET /items/1
    200: "b"

GET /items/2
    204:

GET /items/3
    404: Not Found

33
我只想说,你的例子简洁明了。干得好! - D. Visser
如果不是一个位置数组而是一个字符串搜索,你会使用它吗?/item/a /item/c - aQ123
1
我认为,/item/c 应该语义上是一个未找到的 NotFound。 - Hasan Manzak

95

204 No Content

服务器已经满足请求但不需要返回实体正文,并且可能希望返回更新的元信息。响应中可以包含新的或更新的元信息,以实体标头的形式提供,如果存在,则应与请求变量相关联。

根据RFC 2616状态码204的规范,我认为对于一个GET请求来说,这是一个有效的选择。

404 Not Found200 OK空正文和204 No Content三种状态码完全不同,有时我们不能使用正确的状态码,但是“弯曲规则”会让你在未来某一天付出代价。所以,如果可以使用正确的状态码,就请使用它!

我认为选择GET还是POST是非常个人化的,因为两者都能够完成工作,但我建议您保留POST而不是GET,有以下两个原因:

  • 您希望另一部分(如果我理解正确,则是servlet)执行操作而不是从中检索数据。
  • 如果URL中没有参数存在,则默认情况下GET请求是可缓存的,而POST请求不可缓存。

12
我不知道GET请求可以被缓存而POST请求不行,这是一个很有用的信息。谢谢。 - ecbrodie
2
@ecbrodie 不用谢,你可以在这里找到有关GET和POST请求缓存的更多信息:http://tools.ietf.org/html/rfc2616#section-9.3 - Satevis

22

您目前的POST和HTTP 204响应的组合是可以的。

使用POST作为GET的通用替代方式不受RFC支持,因为每个请求都有自己特定的目的和语义。

GET的目的是检索资源。因此,虽然允许使用HTTP 204响应,但这不是最佳选择,因为响应中期望包含内容。如果服务器无法提供所请求的资源,则HTTP 404未找到HTTP 410已删除将是更好的选择。

RFC还明确指出了HTTP 204作为PUT、POST和DELETE的适当响应,但在GET中省略了它。

请参阅RFC以获取GET的语义

还有其他可以返回没有内容的响应代码,比HTTP 204更合适。

例如,对于条件GET,您可以收到一个HTTP 304未修改的响应,其中不包含正文内容。


15

POST/GET与204一起使用看起来很好,并且也能够正常工作。

文档说明: 2xx--这类状态代码表示服务器已成功接收、理解、接受并处理了客户端请求的操作,而 4xx-- 4xx状态代码用于客户端似乎出现错误的情况。

由于在服务器上成功地接收、理解和处理了请求。结果是资源未找到。因此,在这种情况下,这不是客户端错误或客户端犯了错误。

因此,应该是2xx系列的代码,而不是4xx。在这种情况下,发送204(无内容)比404或410响应更好。


2

返回204的Http GET是完全可以接受的,返回404也同样可以。

重要的是您为API定义设计标准/指南,以便所有终端点都一致地使用状态码。

例如:

  • 您可能会指示返回资源集合的GET终端点如果集合为空,则返回204。在这种情况下,如果2019年4月没有投诉记录,GET /complaints/year/2019/month/04将返回204。这不是客户端错误,因此我们返回成功状态码(204)。另一方面,如果投诉编号12345不存在,则GET /complaints/12345可能返回404。
  • 如果您的API使用HATEOAS,则204可能是一个坏主意,因为响应应包含导航到其他状态的链接。

如果你要返回一个集合,那就直接返回这个集合。200 => []。这对客户端来说更好。 - AntiCZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接