97

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

例子:

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

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

4

7 回答 7

140

不,发送带有错误正文的 200 是非常不正确的

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

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

于 2015-01-13T13:05:33.207 回答
61

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

于 2015-01-13T12:01:49.997 回答
16

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

不良做法:

示例 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

于 2020-07-23T04:34:11.947 回答
13

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

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

基本上 HTTP 200 意味着哪个服务器正确处理了用户请求(如果飞机上没有座位也没关系,因为用户请求被正确处理,它甚至可以返回飞机上可用的座位数,所以会有完全没有业务逻辑错误或者业务逻辑可以在客户端。业务逻辑错误是一个抽象的含义,但HTTP错误更明确)。

于 2015-08-12T07:07:11.730 回答
10

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

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

请参阅此软件工程答案

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

于 2018-07-11T07:58:39.693 回答
5

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

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

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

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

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

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

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

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

于 2019-08-08T00:21:30.710 回答
3

HTTP 是处理通过 Internet 传输数据的协议。

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

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

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

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

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

于 2018-09-10T12:59:32.680 回答