HTTP/1.1 specification (RFC 2616)对status code 400, Bad Request (§10.4.1)的含义有以下说法:
请求无法理解 由于语法错误导致的服务器。 客户端不应该重复 请求不加修改。
现在,在一些基于HTTP的API中似乎普遍存在使用400来表示逻辑而不是语法错误的请求。我的猜测是API正在这样做以区分400(客户端引发的)和500(服务器引发的)。使用400表示非语法错误是否可接受或不正确?如果可以接受,RFC 2616上是否有注释参考,可以更深入地了解400的预期用途?
示例:
答案 0 :(得分:62)
状态422(RFC 4918, Section 11.2)浮现在脑海中:
422(不可处理实体)状态代码表示服务器理解请求实体的内容类型(因此415(不支持的媒体类型)状态代码不合适),并且请求实体的语法是正确的(因此400 (错误请求)状态代码不合适)但无法处理包含的指令。例如,如果XML请求主体包含格式正确(即语法正确)但语义错误的XML指令,则可能会出现此错误情况。
答案 1 :(得分:14)
截至目前,HTTPbis规范的最新草案旨在取代并使RFC 2616过时,states:
400(错误请求)状态代码表示服务器不能或 不会处理请求,因为收到的语法无效, 无意义的,或超过服务器愿意的一些限制 处理。
这个定义虽然可能会有所变化,但却批准了广泛使用的用400响应逻辑错误的做法。
答案 2 :(得分:6)
HTTPbis将解决400 Bad Request的措辞,以便它也涵盖逻辑错误。所以400将合并422。
来自https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-18#section-7.4.1
“由于客户端错误(例如,语法格式错误),服务器无法或不会处理请求”
答案 3 :(得分:2)
可能有人认为,在您的请求中包含不正确的数据会出现语法错误,即使您在HTTP级别的实际请求(请求行,标题等)在语法上有效。
例如,如果将Restful Web服务记录为接受自定义XML内容类型为application/vnd.example.com.widget+xml
的POST,而您发送一些乱码文本或二进制文件,那么将其视为语法错误 - 您的请求正文不是预期的形式。
我不知道有任何正式的提及,但通常似乎是解释RFC 2616。
更新:请注意RFC 7231 §6.5.1中修订后的措辞:
400(错误请求)状态代码指示服务器由于被认为是客户端错误的某些内容而不能或不会处理该请求,例如,格式错误的请求语法,无效的请求消息成帧或欺骗性请求路由。
似乎支持这个论点,而不是现在已经过时的RFC 2616 §10.4.1,它只是说:
由于语法格式错误,服务器无法理解该请求。客户不应该在没有修改的情况下重复请求。
答案 4 :(得分:2)
尽管我一直使用400来表示逻辑错误,但我必须说在这种情况下返回400是错误的,因为spec的读取方式。这就是为什么我这么认为,逻辑错误可能是与另一个实体的关系失败或不满足,并且对另一个实体进行更改可能导致同样的精确度稍后通过。就像尝试(完全假设的)在员工不存在时将员工添加为部门成员(逻辑错误)。将员工添加为成员请求可能会失败,因为员工不存在。但是,在将员工添加到系统后,同样的确切请求可能会通过。
只需2美分......我们需要律师和法官现在解释RFC中的语言:)
谢谢你, Vish
答案 5 :(得分:1)
在Java EE服务器上,如果您的URL引用了不存在的“Web应用程序”,则会返回400。这是“语法错误”吗?取决于语法错误的含义。我会说是的。
在英语语法规则中规定了词性之间的某些关系。例如“鲍勃与玛丽结婚”在语法上是正确的,因为它遵循模式{Noun + Verb + Noun}。而 “鲍勃婚姻玛丽”在语法上是不正确的,{Noun + Noun + Noun}。
简单URL的语法{protocol +:+ // + server +:+ port}。根据这个“http://www.google.com:80”在语法上是正确的。
但是“abc://www.google.com:80”怎么样?它似乎遵循完全相同的模式。但是真的 这是一个语法错误。为什么?因为'abc'不是DEFINED协议。
关键在于确定我们是否有400情况需要的不仅仅是解析字符和空格以及分隔符。它还必须认识到什么是有效的“词性”。
答案 6 :(得分:1)
这很难。
我认为应该;
仅当客户端有权更改请求,标头或正文时,才返回4xx错误,这将导致请求以相同的意图成功执行。
当未发生预期的突变时,即未发生DELETE或PUT未进行任何更改时,返回错误范围代码。但是,POST更有趣,因为该规范说应该将其用于在新位置创建资源或仅处理有效负载。
使用Vish答案中的示例,如果请求打算将员工Priya添加到部门Marketing中,但未找到Priya或她的帐户已存档,则这是应用程序错误。
该请求运行正常,它已符合您的应用程序规则,客户端正确执行了所有操作,匹配了ETag等。
因为我们使用的是HTTP,所以我们必须根据请求对资源状态的影响做出响应。这取决于您的API设计。
也许是您设计的。
PUT { updated members list } /marketing/members
返回成功代码将表明该资源的“替换”有效;资源上的GET可以反映您的更改,但不会。
因此,现在您必须选择合适的否定HTTP代码,这是棘手的部分,因为这些代码强烈地是针对HTTP协议而不是您的应用程序的。
当我阅读官方的HTTP代码时,这两个看起来很合适。
409(冲突)状态代码表示由于与目标资源的当前状态冲突而无法完成请求。此代码用于用户可能能够解决冲突并重新提交请求的情况。服务器应生成有效载荷,该有效载荷应包含足以使用户识别冲突根源的信息。
和
500(内部服务器错误)状态代码表示服务器遇到意外状况,阻止其满足请求。
尽管我们传统上将500视为未处理的异常:-/
我认为发明自己的状态代码并不无道理,只要它始终如一地应用和设计即可。
这种设计更易于处理。
PUT { membership add command } /accounts/groups/memberships/instructions/1739119
然后,您可以设计API来始终成功创建指令,它返回 201 Created 和 Location 标头,并且该指令中的任何问题都包含在该新指令中资源。
POST更像是将上一个PUT放到新位置。 POST允许对消息进行任何类型的服务器处理,从而打开诸如“操作成功失败”之类的设计。
可能您已经编写了一个用于执行此操作的API,即一个网站。您过帐付款表格,由于信用卡号错误,已成功被拒绝。
使用POST时,是否返回200或201以及拒绝消息取决于是否创建了新资源,并且该资源可用于其他位置的GET。
说了这么多,我倾向于设计需要更少PUT的API,也许只是更新数据字段,而调用规则和处理的动作和东西或可能会有更大的预期失败的东西可以设计为发布说明表格。
答案 7 :(得分:0)
就我而言:
我收到400错误的请求,因为我错误地设置了Sub Draft()
Worksheets("Material Check").Range("B3:B6").Copy _
Destination:=Worksheets("Archive").Range("A2:D2")
End Sub
。我更改了内容类型,然后能够成功获得响应。
问题之前:
content-type
之后(固定):
ClientResponse response = Client.create().resource(requestUrl).queryParam("noOfDates", String.valueOf(limit))
.header(SecurityConstants.AUTHORIZATION, formatedToken).
header("Content-Type", "\"application/json\"").get(ClientResponse.class);