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


77

我想知道HTTP 200 OK服务器端发生错误时返回的错误是否正确(错误详细信息将包含在响应正文中)。

例:

  1. 我们正在发送 HTTP GET
  2. 服务器端发生了意外情况。
  3. 服务器HTTP 200 OK在响应内返回错误的状态代码(例如{"status":"some error occurred"}

这是正确的行为吗?我们应该将状态代码更改为200以外的其他值吗?


14
HTTP 200表示在HTTP级别上可以传输。这与“业务代码”的成功或失败无关。在这种情况下,HTTP 200指示您的“业务代码错误消息”已成功传输;-)或者,您可以让服务器使用HTTP 500进行响应,表示“内部错误”。对于服务器上的技术或不可恢复的问题,这更典型。
geert3 2015年

有人可以确认吗?我与一些程序员进行了交谈,我听到了不同的意见。
krzakov

3
请改用代码412。
Dima Tisnek '17

6
看看这两个相互矛盾的答案,这恰恰是为什么Stack Overflow应该更鼓励讨论的原因。
wobbily_col

1
我看到它的方式基于预期的意图。如果调用方期望的是非,则是业务响应,应将真假都作为200发送回去。另一方面,如果有说处理订单删除的API-对该API的调用期望订单已存在。如果没有,那么404在这里有意义,而不是200。所以这不是一个适合所有情况的答案。
MovieMe

Answers:


107

不,这是非常不正确的。

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

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


13
不,我完全不同意第一部分声称可以返回
200。–朱利安·雷施克

1
请参阅我对其他答案的评论。
geert3

2
我认为200 OK错误在某些情况下可能是适当的。但是在这种情况下,客户端发出GET请求来询问一些资源,却没有获得该客户端所请求的资源,但是得到了其他东西,这是错误的。如果是服务器错误5XX,则客户端4XX(例如,被请求的资源)不存在404。我的看法。
2015年

10
在拥有大型财富500强电子商务网站的最新经验之后,我不得不不同意这个答案,即不使用200来表示错误。该公司特别将一切归还200 OK。Spring Java可以处理的所有错误都将返回200,并且在正文中您将具有errors属性。就那么简单。无需尝试找出哪些错误属于哪些晦涩的HTTP代码。
prograhammer

4
“ HTTP是一种应用程序协议。” 好吧,虽然维基百科同意此定义,但必须说这里的应用程序是指IP应用程序层-维基百科列出了HTTP,Telnet,FTP和SSH之类的IP通信的所有应用程序。这是一样的我的应用/业务逻辑,它使用说通信。因此,发送带有特定于应用程序的错误消息的HTTP 200是非常合理的。
杰夫·沃德,

42

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

HTTP 200与您的“业务代码”的成功或失败无关。在您的示例中HTTP 200,如果没有技术问题阻止业务逻辑正常运行,则表明您的“业务代码错误消息”已成功传输是可接受的状态。

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

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


8
看到。HTTP状态代码是技术响应,不是业务逻辑响应。我可以很好地想象一个HTTP / REST API,其中由于业务逻辑明显失败而返回HTTP 200。例如:我是一个HTTP客户端,预订飞机上的航班。我的所有参数都可以,从技术上讲,没有理由使用HTTP 4xx。服务器运行状况良好,没有HTTP 5xx。然而飞机已经满了。响应是JSON块,说明了这一事实:{"booking":"failed","reason":"plane is full"}。为此,获取HTTP 200完全可以,实际上(IMHO)这将是唯一有效的HTTP状态代码。
geert3

24
“ HTTP 200与您的“业务代码”的成功或失败无关,是的,它确实如此。HTTP是一种应用程序协议,其状态代码反映了这一点。请参阅RFC 7231,第6节“状态代码元素是三位数的整数代码,表示尝试理解并满足请求的结果”,“满足”表示已成功处理请求。如果在应用程序中的任何时候发生错误(是否尝试预订全座位)飞行是一个错误是另一个讨论),你不应该返回2xx状态代码。
CodeCaster

11
看一下4xx和5xx代码。它们显然是针对技术问题的,在这种意义上应采用“理解并满足要求”。如果服务器具有不支持的媒体类型(415)或不允许使用该方法(405),则服务器无法理解该请求。如果超出带宽限制(509)或存在网络读取超时(598),则服务器无法满足请求。但是,在一个完整的平面,预订座位无关这些问题,这里的要求是技术上的理解和满足,即使飞机满,ERGO:HTTP 200
geert3

14
用一个实际的例子来证明我的观点。Google Maps REST API。developers.google.com/maps/documentation/directions/…所有状态代码和错误消息均以JSON / XML块形式返回,但在每种情况下,HTTP 200均以HTTP级别返回。
geert3

8
有趣的是,我尝试编辑我的评论,因为我在完成之前不小心提交了评论,因此回复了500,“您只能编辑您的评论5分钟”。因此,即使我的提交“成功”并且错误就在我这一边,但它的响应为500。__(ツ)_ //我也想支持您这一观点的观点是有效的,即使对于这个特定答案来说,可能不。
radixhound

11

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

因此,HTTP 200可以解决业务逻辑错误。但是,HTTP错误代码涵盖的所有错误都应使用它们。

基本上,HTTP 200表示哪个服务器可以正确处理用户请求(如果飞机上没有席位,由于用户请求得到了正确处理,无论如何,它甚至可以只返回飞机上的一些席位,因此根本没有业务逻辑错误,也没有业务逻辑可以在客户端。业务逻辑错误是抽象的含义,但是HTTP错误更明确)。


6

为了明确起见,您应该在适合协议的地方使用HTTP错误代码,而不要使用HTTP状态代码发送业务逻辑错误。

诸如余额不足没有可用的出租车错误的用户名/密码之类的200错误都有资格通过响应正文中的应用程序特定错误处理获得HTTP状态。

看到这个软件工程答案

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


这可能是一个见解,但我不同意。这些错误的存在是有原因的,无需重新发明发送标准错误的方法,只需使用HTTP规范即可。如果请求格式错误,则发送400,如果用户无权访问该资源,则发送403,等等。httpstatuses.com
Alexandre Testu,

3

我认为,如果我们考虑现实生活,就会解决这些问题。

不良做法:

范例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???
}

范例2:

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

良好做法:

 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 ...
}

这只是我个人的观点,每个人都可以实施它,因为它是最舒适或最需要的。

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


2

HTTP是用于处理Internet上数据传输的协议。

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

HTTP错误代码未处理正在传输的数据。只有传输方法。

HTTP不能说“好吧,这个答案是gobbledigook,但是这里是”。它只是说200 OK

即:我已经完成了将它交给您的工作,其余的一切取决于您。

我知道已经回答了这个问题,但是我用我能理解的话说了一下。对不起,我很重复。


我还要说,由程序员和开发人员来适当地报告服务器端错误,并让用户知道服务器端存在什么类型的问题。例如,很抱歉,此页面已损坏,或者例如,我现在正在忙于更新数据库,请尽快与您联系。
克里斯·格罗夫斯

2

我认为人们对应用程序逻辑和协议问题的重视程度过高。重要的是,响应应该合理。如果您有一个提供动态资源的API并向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,并带有可区分的响应主体。这不是理想的选择,但是如果没有解决问题并积极地引起问题,则可能需要解决更大,更重要的问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.