HTTP/1.1规格(RFC 2616) 有以下内容要说 状态代码400,不良请求(§10.4.1):

由于畸形的语法,服务器无法理解该请求。客户不应在没有修改的情况下重复请求。

如今,几个基于HTTP的API似乎有一种一般实践,可以使用400来表示 逻辑 而不是一个 句法 请求错误。我的猜测是API正在这样做以区分 400 (客户引起的)和 500 (服务器诱导)。使用400来指示非句法错误是可以接受的还是不正确的?如果可以接受,RFC 2616上是否有带注释的参考,可以更深入地了解400的预期用途?

例子:

有帮助吗?

解决方案

截至这个时候, httpbis 规格,旨在替换并使RFC 2616过时, 状态:

400(不良请求)状态代码表示服务器无法或不会处理该请求,因为接收的语法无效,荒谬或超出了服务器愿意处理的内容的一定限制。

当然,该定义虽然仍可能发生变化,但批准了以400为400来响应逻辑错误的广泛使用的实践。

其他提示

状态422(RFC 4918,第11.2节)想到:

422(无法处理的实体)状态代码意味着服务器了解请求实体的内容类型(因此415(不支持的媒体类型)状态代码不合适),并且请求实体的语法是正确的(因此是400(因此,请求不好(不良请求) )状态代码是不合适的),但无法处理包含的说明。例如,如果XML请求主体包含良好的(即句法正确),但在语义上错误的XML指令时,可能会发生此错误条件。

HTTPBI将解决400个不良请求的措辞,以便涵盖逻辑错误。因此400将合并422。

https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-18#section-7.4.1
“由于客户端错误(例如,畸形语法),服务器无法处理或不会处理该请求””

即使我一直在使用400来表示逻辑错误,但我不得不说,在这种情况下,返回400是错误的,因为规格的读取方式。这就是为什么我这样认为,合乎逻辑的错误可能是与另一个实体的关系失败或不满足,并且对其他实体进行更改可能会导致以后通过相同的准确。就像尝试(完全假设)在不存在该员工时(逻辑错误)时(完全假设)将员工作为部门的成员。将员工作为会员请求添加可能会失败,因为员工不存在。但是,在将员工添加到系统中后,可以通过相同的确切请求。

只是我的2美分...如今,我们需要律师和法官来解释RFC的语言:)

谢谢你,vish

可以说,您的请求中有不正确的数据 语法错误,即使您在HTTP级别(请求行,标题等)在句法上有效的实际请求也是有效的。

例如,如果将Rentful Web服务记录为接受具有自定义XML内容类型的帖子 application/vnd.example.com.widget+xml, ,而是您发送了一些Gibberish的纯文本或二进制文件,将其视为语法错误似乎可以重现 - 您的请求主体不在预期的形式中。

我不知道有任何官方引用来支持这一点,就像往常一样,这似乎是对RFC 2616的解释。

更新: 注意修订的措辞 RFC7231§6.5.1:

400(不良请求)状态代码表示,由于认为是客户端错误,畸形的请求语法,无效的请求消息框架或欺骗性请求路由,服务器无法或不会处理该请求。

似乎比现在被淘汰的更多支持这个论点 RFC2616§10.4.1 只是说:

由于畸形的语法,服务器无法理解该请求。客户不应在没有修改的情况下重复请求。

在Java EE服务器上,如果您的URL指的是不存在的“ Web -Application”,则将返回400。这是“语法错误”吗?取决于您所说的语法错误。我会说是的。

用英语语法规则规定语音部分之间的某些关系。例如,“鲍勃婚姻玛丽”在句法上是正确的,因为它遵循模式{noun +动词 +名词}。而“鲍勃婚姻玛丽”在句法上是不正确的,{名词 +名词 +名词}。

简单URLIS {协议 +: + // + Server +: + port}的语法。根据这个 ”http://www.google.com:80“在句法上是正确的。

但是“ abc://www.google.com:80”呢?它似乎遵循完全相同的模式。但实际上这是一个语法错误。为什么?因为“ ABC”不是定义的协议。

关键是确定我们是否有400个情况所需的不仅仅是分析角色,空间和定界符。它还必须认识到什么是有效的“语音部分”。

这是困难的。

我认为我们应该;

  1. 仅当客户端有权更改请求,标题或正文时,返回4xx错误,这将导致请求以相同的意图成功。

  2. 返回错误范围代码当没有发生预期突变时,即没有发生删除或删除没有任何更改。但是,帖子更有趣,因为规格说应该使用它在新位置创建资源,或者只是处理有效负载。

使用Vish答案中的示例,如果请求打算将员工Priya添加到部门营销中,但没有找到Priya或她的帐户已存档,则这是一个申请错误。

该请求正常工作,符合您的应用程序规则,客户完成了所有操作,符合的ETAG等。

因为我们使用的是HTTP,所以我们必须根据请求对资源状态的影响做出响应。这取决于您的API设计。

也许您设计了这个。

PUT { updated members list } /marketing/members

返回成功代码将表明资源的“更换”有效;获取资源将反映您的更改,但不会。

因此,现在您必须选择合适的负HTTP代码,这是棘手的部分,因为这些代码是针对HTTP协议而不是您的应用程序的。

当我阅读官方HTTP代码时,这两个看起来合适。

409(冲突)状态代码表明,由于与目标资源的当前状态发生冲突,该请求无法完成。此代码用于用户可能能够解决冲突并重新提交请求的情况。服务器应生成有效负载,其中包含足够的信息,以供用户识别冲突的来源。

500(内部服务器错误)状态代码表明服务器遇到了一种意外条件,阻止其满足请求。

尽管我们传统上认为500是一个未经治疗的例外: - /

我认为,只要它始终如一地应用和设计,就不会发明自己的状态代码。

这种设计更容易处理。

PUT { membership add command } /accounts/groups/memberships/instructions/1739119

然后,您可以设计自己的API以始终成功创建指令,它返回 201创建地点 标题和指令的任何问题都在该新资源内持有。

帖子更像是最后一个新地点。帖子允许任何类型的服务器处理消息,该帖子打开了诸如“动作成功失败”之类的设计。

可能您已经写了一个可以做到这一点的API,一个网站。您发布了付款表,并因信用卡号错误而成功拒绝。

有了帖子,无论您是返回200还是201和拒绝消息都取决于是否创建了新资源,并且可以在另一个位置获得。

总而言之,我倾向于设计需要更少的投票的API,也许只是更新数据字段,以及调用规则和处理的操作和内容,或者只是有更大的预期失败机会,可以设计用于发布指令形式。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top