在响应正文中返回http 200 OK并出错

krz*_*kov 55 http http-status-code-400 http-status-code-200

我想知道HTTP 200 OK在服务器端发生错误并且响应正文内部出现一些错误时返回是否正确.

例:

  1. 我们正在发送 http GET
  2. 服务器端出现意外情况.
  3. 服务器http 200 OK在响应中返回错误状态代码(例如,{"status":"some error occured"}

是不是正确的行为?我们不应该改变状态代码吗?

Jul*_*hke 83

不,这是非常不正确的.

HTTP是一种应用程序协议.200意味着响应包含表示所请求资源的状态的有效载荷.错误消息通常不是该资源的表示.

如果在处理GET时出现问题,则正确的状态代码为4xx("你搞砸了")或5xx("我搞砸了").

  • 不,我完全不同意第一部分,声称可以返回200. (8认同)
  • “HTTP 是一种应用程序协议。” 好吧,虽然[维基百科同意](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol) 有这个定义,但必须说这里的**应用程序**指的是[IP 应用层](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol) /en.wikipedia.org/wiki/Application_layer)——维基百科列出了诸如 HTTP、Telnet、FTP 和 SSH 之类的东西——IP 通信的所有 _applications_。这与使用上述通信的应用程序/业务逻辑**不**相同。因此,发送带有特定于应用程序的错误消息的 HTTP 200 是非常合理的。 (8认同)
  • 在最近有一个非常大的财富500电子商务网站的经验后,我不得不反对这个暗示不使用200错误的答案.特别是这家公司将所有东西都归还200 OK.Spring Java可以处理的所有错误都返回为200,并且在正文中您将拥有可用的errors属性.就那么简单.无需尝试弄清楚哪些错误属于隐藏的HTTP代码. (7认同)
  • 我认为200 OK错误在某些情况下可能是适当的。但是在这种情况下,客户端发出GET请求来询问一些资源,却没有得到该客户端所请求的资源,但是得到了其他东西,这是错误的。如果是服务器错误5XX,则客户端4XX(例如,所请求的资源)不存在404。我的看法。 (2认同)

gee*_*rt3 26

HTTP状态代码说明了HTTP协议.HTTP 200表示HTTP级别的传输正常(即请求技术上正常,服务器能够正确响应).请参阅此Wiki页面以获取所有代码及其含义的列表.

HTTP 200与"业务代码"的成功或失败无关.在您的示例HTTP 200中,可接受的状态表示您的"业务代码错误消息"已成功传输,前提是没有任何技术问题阻止业务逻辑正常运行.

或者,HTTP 5xx如果服务器上发生技术或不可恢复的问题,您可以让服务器响应.或者HTTP 4xx如果传入的请求有问题(例如错误的参数,意外的HTTP方法......)同样,这些都表示技术错误,而HTTP 200表示没有技术错误,但不保证业务逻辑错误.

总结:是的,在http响应中发送错误消息(非技术问题)以及HTTP状态200是有效的.这是否适用于您的情况取决于您.例如,如果客户端要求的文件不存在,则更像是a 404.如果服务器上的配置错误可能是500.如果客户要求在预订满的飞机上的座位,那将是200你的"实施"将决定如何识别/处理这个(例如带有a的JSON块{ "booking","failed" })

  • _"HTTP 200与"业务代码"的成功或失败无关_是 - 确实如此.HTTP是一种应用程序协议,其状态代码反映了这一点.请参阅[RFC 7231,第6节](https:// tools.ietf.org/html/rfc7231#section-6):_"状态代码元素是一个三位整数代码,给出尝试**理解和满足**请求"_,"的结果"成功处理请求.如果在应用程序中的任何一点发生_error_(无论是试图预订完整航班上的座位都是错误是另一种讨论),您不应该返回2xx状态代码. (18认同)
  • 用一个实际的例子证明我的观点.Google Maps REST API.https://developers.google.com/maps/documentation/directions/#sample-response所有状态代码和错误消息都以JSON/XML块的形式返回,但在每种情况下都会在HTTP级别返回HTTP 200. (10认同)
  • 看到.HTTP状态代码是技术响应,而不是业务逻辑响应.我可以想象一个HTTP/REST API,其中返回HTTP 200,显然是失败的业务逻辑.例如:我是在飞机上预订航班的HTTP客户端.我的所有参数都没问题,技术上没有理由使用HTTP 4xx.服务器运行正常,没有HTTP 5xx.飞机已满了.响应是一个JSON块,解释了这个事实:`{"预订":"失败","理由":"飞机已满"}.获得HTTP 200是完全可以的,事实上(恕我直言)这将是唯一有效的HTTP状态代码. (8认同)
  • 看看4xx和5xx代码.它们显然是出于技术问题,在这个意义上应该"理解并满足要求".如果请求具有不支持的媒体类型(415)或者不允许该方法(405),则服务器无法理解该请求.如果超出带宽限制(509)或网络读取超时(598),则服务器无法满足请求.但是在一架完整的飞机上预订座位与这些问题无关,这里的请求在技术上已被理解并且即使飞机已经满了也能满足,ergo:HTTP 200. (8认同)
  • 有趣的是,我试图编辑我的评论,因为我在完成之前意外地提交了它,并且SO回复了500'你只能编辑你的评论5分钟'.所以即使我的提交是"成功的"并且错误在我身边,它也以500响应.¯\ _(ツ)_ /¯我也想支持你的论证方有效,即使对于这个特定的答案它是可能不是. (8认同)
  • 好吧,谷歌做错了.它发生了. (7认同)
  • 他们为INVALID_REQUEST(400),OVER_QUERY_LIMIT(429),REQUEST_DENIED(403)和UNKNOWN_ERROR(500)返回200.使用REST,您使用HTTP作为应用程序协议.没有规范,所以它总是模糊和基于意见,但你的"HTTP状态代码仅适用于HTTP级别"太严格了.HTTP允许应用程序根据需要返回状态代码,请参阅:_"403表示服务器理解请求但拒绝授权"_,_"404表示服务器[..]不愿意透露存在的请求"_. (6认同)
  • 谷歌滥用HTTP协议并没有做到这一点.每个"状态代码"都有一个适当的HTTP等价物,只有OK才能返回200. (3认同)
  • 您与最大的互联网公司开发的最广泛使用的实用 REST API 之一相矛盾,这并不能使您的陈述正确,我会说相反。再说一次:他们正确地返回 HTTP 200,因为 HTTP 协议**没有**失败。一些底层业务逻辑失败了,因此他们通过 HTTP 200 响应中的 XML 进行通信。当然,有些可能是 4xx,但他们可能会选择在这些情况下保持一致性。 (2认同)
  • @geert3 你有一个正确的论点,但你没有抓住原始问题的重点。_一些意外_发生在服务器端。所以正确的响应应该是 5xx 响应。 (2认同)
  • Facebook Graph API也为所有内容返回200 OK. (2认同)
  • 我同意这一点,除了“404 NotFound”。返回未找到错误时有点复杂:当客户端请求不存在的文件时,404 响应是正确的,但当客户端搜索某些内容时,它仍然是正确的方法吗?(例如,客户正在搜索标题为“机器学习”的书籍)。服务器是否应该响应 404 或类似 `{ "total": 0 }` 之类的内容? (2认同)
  • @Simon.Li 实际上,您返回 `HTTP 404` 以指示“与您的查询不匹配”的示例在我看来是一个非常明确的论据 _against_ 使用(技术)HTTP 错误代码解决“业务逻辑”问题。没有找到书籍这一事实是一个商业问题。显然找到了查询结果页面(虽然是空的),因此是“HTTP 200”。 (2认同)
  • 对于那些认为 HTTP 是应用程序协议的人,请参阅 [我上面的评论](/sf/ask/1954507621/#comment96221959_27922900)。总结:IP“应用层”!=我的应用程序/业务逻辑。 (2认同)

Ale*_*ius 9

即使我想将业务逻辑错误作为HTTP代码返回,也没有针对该错误的可接受的HTTP错误代码而不是使用HTTP 200,因为它将歪曲实际错误.

因此,HTTP 200将有利于业务逻辑错误.但是HTTP错误代码所涵盖的所有错误都应该使用它们.

基本上HTTP 200意味着服务器正确处理用户请求(如果飞机上没有座位,则无论因为用户请求是否正确处理,它甚至可以返回飞机上可用的多个座位,因此会有根本没有业务逻辑错误或者业务逻辑可以在客户端.业务逻辑错误是一个抽象的含义,但HTTP错误更明确).


ved*_*ant 9

澄清一下,您应该在适合协议的地方使用 HTTP 错误代码,而不是使用 HTTP 状态代码来发送业务逻辑错误。

诸如余额不足、没有可用出租车、错误的用户/密码等200错误符合 HTTP 状态,并在响应正文中处理特定于应用程序的错误。

请参阅此软件工程答案:

我会说最好明确协议的分离。让HTTP服务器和Web浏览器做好自己的事情,并让应用程序做它自己的事情。应用程序需要能够发出请求,它需要响应——以及它关于如何请求、如何解释响应的逻辑可能比 HTTP 透视图更(或更少)复杂。

  • 这可能是一个观点问题,但我不同意。这些错误的存在是有原因的,不需要重新发明发送标准错误的方法,只需使用 HTTP 规范即可。如果请求格式错误,则发送 400,如果用户无权访问资源,则发送 403 等。https://httpstatuses.com/ (2认同)
  • 这可能归结为“业务逻辑”。在上面的例子中,我认为,余额不足和没有出租车是业务逻辑,200 是合适的。那么错误的用户/密码、格式错误的请求、访问被拒绝并不是真正的业务逻辑,而是特定于用户的技术问题,因此 400 级响应是合适的。 (2认同)

sna*_*arf 8

我认为人们过于重视应用程序逻辑而不是协议问题。重要的是响应应该有意义。如果您有一个提供动态资源的 API,并且对 X 发出了请求,而 X 是从带有数据 Z 的模板 Y 派生的,并且 Y 或 Z 当前不可用,该怎么办?这是业务逻辑错误还是技术错误?正确答案是:“谁在乎呢?”

您的 API 和您的响应必须易于理解且一致。它应该符合某种规范,并且该规范应该定义什么是有效响应。符合有效响应的内容应生成 200 代码。不符合有效响应的内容应生成 4xx 或 5xx 代码,指示无法生成有效响应的原因。

如果您的规范对有效响应的定义允许{ "error": "invalid ID" },那么它就是成功的响应。如果您的规范没有做到这一点,那么用 200 代码返回该响应将是一个糟糕的决定。

我将与调用函数进行类比parseFoo。当你打电话时会发生什么parseFoo("invalid data")?它是否返回错误结果(可能为 null)?或者它会抛出异常吗?对于一种方法或另一种方法是否正确,许多人会采取近乎宗教的立场,但最终取决于 API 规范。

“状态代码元素是一个三位数整数代码,给出尝试理解和满足请求的结果”

显然,对于“成功返回错误”是否构成HTTP成功或错误存在不同的意见。我看到不同的人以不同的方式解释相同的规格。所以,当然要选择一边,但也要接受这样的事实:无论哪种方式,整个世界都不会同意你的观点。我?我发现自己处于中间位置,但我会提供一些常识性的考虑。

  1. 如果您的服务器端代码在分派请求时捕获意外异常,这听起来就像500 Internal Server Error. 这似乎是OP的情况。应用程序不应200因意外错误而返回 a,但另请参阅第 3 点。
  2. 如果您的服务器端代码应该能够正常处理给定的无效输入,并且它不构成“异常”错误条件,那么您的规范应该容纳提供有意义的诊断信息的 HTTP 200 响应。
  3. 最重要的是:有一个规格。使其保持一致。坚持下去。

在OP的情况下,听起来你有一个事实上的标准,未处理的异常会产生一个带有可区分响应主体的200。这并不理想,但如果它没有破坏事物并主动引发问题,那么您可能有更大、更重要的问题需要解决。


Jos*_*tes 8

我认为如果我们考虑一下现实生活,这些问题就会迎刃而解。

不良做法:

示例 1:

Darling everything is FINE/OK (HTTP CODE 200) - (Success):
{
  ...but I don't want us to be together anymore!!!... (Error)
  // Then everything isn't OK???
}
Run Code Online (Sandbox Code Playgroud)

示例 2:

You are the best employee (HTTP CODE 200) - (Success):
{
  ...But we cannot continue your contract!!!... (Error)
  // Then everything isn't OK???
}
Run Code Online (Sandbox Code Playgroud)

良好做法:

 Darling I don't feel good (HTTP CODE 400) - (Error):
{
  ...I no longer feel anything for you, I think the best thing is to separate... (Error)
  // In this case, you are alerting me from the beginning that something is wrong ...
}
Run Code Online (Sandbox Code Playgroud)

这只是我个人的意见,每个人都可以按照自己最舒服或最需要的方式实施。

注意:这个解释的想法来自一个好朋友@diosney


小智 7

HTTP 是处理通过互联网传输数据的协议。

如果传输由于某种原因中断,HTTP 错误代码会告诉您为什么无法将其发送给您。

正在传输的数据不由 HTTP 错误代码处理。只是传输方法。

HTTP 不能说“好吧,这个答案是官样文章,但就是这样”。它只是说200 OK。

即:我已经完成了把它交给你的工作,剩下的就看你了。

我知道这个问题已经得到了回答,但我用我能理解的语言表达了它。抱歉有任何重复。