我想知道当服务器端发生错误时返回HTTP 200 OK
是否正确(错误详细信息将包含在响应正文中)。
例:
- 我们正在发送
HTTP GET
- 服务器端发生了一些意外的事情。
- 服务器返回
HTTP 200 OK
状态代码,并在响应中出现错误(例如{"status":"some error occurred"}
)
这是不正确的行为吗?我们是否应该将状态代码更改为 200 以外的其他代码?
不,发送带有错误正文的 200 是非常不正确的
HTTP 是一种应用程序协议。 200 表示响应包含表示所请求资源状态的有效负载。错误消息通常不是该资源的表示形式。
如果在处理 GET 时出现问题,正确的状态代码是 4xx("你搞砸了")或 5xx("我搞砸了")。
状态代码说明了 HTTP 协议。 HTTP 200
意味着在HTTP级别上传输是可以的(即请求在技术上是可以的,服务器能够正确响应)。请参阅此 wiki 页面以获取所有代码及其含义的列表。
HTTP 200 与"业务代码"的成败无关。在您的示例中,HTTP 200
是可接受的状态,指示您的"业务代码错误消息"已成功传输,前提是没有技术问题阻止业务逻辑正常运行。
或者,如果服务器上发生技术问题或不可恢复的问题,您可以让服务器HTTP 5xx
响应。或者HTTP 4xx
传入的请求是否有问题(例如错误的参数、意外的 HTTP 方法......同样,这些都表示技术错误,而HTTP 200
表示没有技术错误,但不保证业务逻辑错误。
总结一下:是的,在 http 响应中发送错误消息(针对非技术问题)以及 HTTP 状态 200 是有效的。这是否适用于您的情况取决于您。例如,如果客户端要求一个不存在的文件,那更像是一个404
。如果服务器上存在配置错误,则可能是500
。如果客户要求在预订满员的飞机上安排座位,那将是200
的,您的"实现"将决定如何识别/处理此问题(例如,带有{ "booking": "failed" }
的 JSON 块
我认为如果我们考虑现实生活,这些问题就会得到解决。
不良做法:
示例 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
即使我想将业务逻辑错误作为 HTTP 代码返回,也没有这样的该错误的可接受的 HTTP 错误代码,而不是使用 HTTP 200,因为它会错误地表示实际错误。
因此,HTTP 200 将有利于业务逻辑错误。但是HTTP错误代码涵盖的所有错误都应该使用它们。
基本上HTTP 200意味着服务器正确处理用户请求(如果飞机上没有座位,那也没关系,因为用户请求被正确处理,它甚至可以只返回飞机上可用的座位数量,因此根本不会有业务逻辑错误或业务逻辑可以在客户端。业务逻辑错误是一个抽象的含义,但HTTP错误更明确)。
为了澄清,您应该在符合协议的地方使用 HTTP 错误代码,而不是使用 HTTP 状态代码来发送业务逻辑错误。
平衡不足、没有可用的 cab、错误的用户/密码等错误符合 HTTP 状态200
,响应正文中特定于应用程序的错误处理。
请参阅此软件工程答案:
我想说的是,最好明确协议的分离。让 HTTP 服务器和 Web 浏览器做自己的事情,让应用程序做自己的事情。应用程序需要能够发出请求,并且需要响应 - 并且其关于如何请求,如何解释响应的逻辑可能比HTTP视角更(或更少)复杂。
我认为人们在应用程序逻辑与协议问题上投入了太多的权重。重要的是,响应应该是有意义的。如果您有一个提供动态资源的 API,并且对从模板 Y 派生的 X 发出了请求,数据为 Z,并且 Y 或 Z 当前不可用,该怎么办?这是业务逻辑错误还是技术错误?正确的答案是,"谁在乎?
您的 API 和响应需要易于理解且一致。它应该符合某种规范,并且该规范应该定义什么是有效的响应。符合有效响应的内容应生成 200 代码。不符合有效响应的内容应生成 4xx 或 5xx 代码,指示无法生成有效响应的原因。
如果您的规范对有效响应的定义允许{ "error": "invalid ID" }
,则这是一个成功的响应。如果您的规范没有做出这种调整,那么返回带有 200 代码的响应将是一个糟糕的决定。
我会打个类比,parseFoo
调用函数。当你打电话给parseFoo("invalid data")
时会发生什么?它是否返回错误结果(可能为空)?还是会引发异常?许多人会对一种方法或另一种方法是否正确采取近乎宗教的立场,但最终这取决于 API 规范。
显然,对于"状态代码元素是一个三位数的整数代码,给出尝试理解和满足请求的结果"
"成功返回错误"是否构成HTTP成功或错误存在意见分歧。我看到不同的人以不同的方式解释相同的规格。所以选择一方,当然,但也要接受无论哪种方式,整个世界都不会同意你的观点。钥匙我发现自己处于中间位置,但我会提供一些常识性的考虑。
- 如果您的服务器端代码在调度请求时捕获意外异常,这听起来像是
500 Internal Server Error
的定义。这似乎是OP的情况。应用程序不应为意外错误返回200
,但也请参阅第 3 点。 - 如果服务器端代码应该能够正常处理给定的无效输入,并且它不构成"异常"错误条件,则规范应适应提供有意义的诊断信息的 HTTP 200 响应。
- 最重要的是:有一个规格,让它保持一致。坚持下去。
在 OP 的情况下,听起来你有一个事实上的标准,即未经处理的异常会产生具有可区分响应正文的 200。这并不理想,但如果它没有破坏事物并主动引起问题,您可能有更大、更重要的问题需要解决。
HTTP是处理互联网数据传输的协议。
如果该传输因任何原因中断,HTTP 错误代码会告诉您为什么无法将其发送给您。
正在传输的数据不由 HTTP 错误代码处理。只有传输方法。
HTTP不能说'好吧,这个答案是gobbledigook,但它就在这里'。 它只是说200 OK
.
即:我已经完成了我的工作,把它交给你,剩下的就看你了。
我知道这已经回答了,但我用我能理解的话说出来。 对不起,任何重复。
我最近正在研究一个在IIS服务器上运行的 ASP.net 项目,如果出现任何问题,IIS 服务器倾向于在响应中附加默认 HTML。
问题是,该项目是一个仅与 json 通信的 API 服务,因此我们希望避免 IIS 服务器这样做。更糟糕的是,操作系统是繁体中文的,所以IIS服务器的默认HTML是BIG-5而不是UTF-8!这让我们的前端开发人员感到非常困惑,因为响应变得胡言乱语。
可悲的是,我也没有特权将自己从使用IIS服务器切换出去,也没有权限更改配置。因此,最后,对于我们可以在后端捕获的所有业务错误和异常,我们发送 200 OK,同时将实际的 http 状态代码/消息包装在响应 json 中。
我认为,尽管这违反了传统的HTTP代码定义,但它避免了对服务器和客户端之间响应的不必要影响。
我不是前端的人,所以不确定 - 但我想这也不再需要查看 HTTP 状态和正文以查找请求是否成功。