400坏请求HTTP错误码含义?

我有一个JSON请求,我张贴到一个HTTP URL。

是否应该将其视为400,其中requestedResource字段存在,但"Roman"是该字段的无效值?

[{requestedResource:"Roman"}]

这是否应该被视为400,其中"blah"字段根本不存在?

[{blah:"Roman"}]
1288533 次浏览

w3.org

10.4.1 400个错误请求

由于格式错误,服务器无法理解请求 语法。客户端不应该重复请求 修改。< / p >

想想期望。

作为客户端应用程序,您希望知道服务器端是否出现了问题。如果服务器需要在blah缺失或requestedResource值不正确时抛出错误,那么400错误将是合适的。

400表示请求格式不正确。换句话说,客户端发送给服务器的数据流没有遵循规则。

在带有JSON有效负载的REST API的情况下,400通常(我认为是正确的)用于根据服务的API规范指示JSON在某种程度上是无效的。

根据这种逻辑,您提供的两个场景都应该是400s。

假设这是XML而不是JSON。在这两种情况下,XML都不会通过模式验证——要么是因为元素未定义,要么是因为元素值不正确。这是个糟糕的要求。这里也是一样。

这两种情况都不是“语法畸形”。语义是错误的。因此,恕我直言,400是不合适的。相反,返回一个200以及某种错误对象,如{ "error": { "message": "Unknown request keyword" } }或其他。

考虑客户机处理路径。语法错误(例如,无效的JSON)是程序逻辑中的错误,换句话说,是某种类型的错误,应该以类似403的方式进行相应的处理;换句话说,有不好的事情发生了。

另一方面,参数值中的错误是语义错误,可能是由于用户输入验证不当造成的。这不是一个HTTP错误(尽管我认为它可能是一个422)。处理路径会有所不同。

例如,在jQuery中,我不希望编写一个单独的错误处理程序来处理500和一些特定于应用程序的语义错误。其他框架,比如Ember,也把400秒和500秒的HTTP错误视为重大错误,要求程序员检测发生了什么,并根据它是否是“真正的”错误进行分支。

400状态码用于任何其他目的,而不是表明请求是畸形的,这是完全错误的。

如果请求有效负载包含一个不能被解析为application/json的字节序列(如果服务器期望该数据格式),则适当的状态代码为415:

服务器拒绝服务请求,因为实体 所请求的资源不支持该请求的格式

如果请求有效负载在语法上正确但语义上不正确,则可以使用非标准的422响应代码,或标准的403状态代码:

服务器理解请求,但拒绝完成它。

.授权不起作用,请求不应重复

选择HTTP响应代码是一项相当简单的任务,可以用简单的规则来描述。唯一经常被遗忘的棘手部分是RFC 7231的第6.5段:

除响应HEAD请求外,服务器应该发送一个 包含错误情况解释的陈述, 以及它是暂时的还是永久的

规则如下:

  1. 如果请求成功,则返回2xx代码(3xx用于重定向)。如果服务器上存在内部逻辑错误,则返回5xx。如果客户端请求中有任何错误,则返回4xx代码。
  2. 从选定的类别中查看可用的响应代码。如果其中一个名称与您的情况非常匹配,您就可以使用它。否则只是回退到x00代码(200,400,500)。如果您怀疑,请退回到x00代码。
  3. 在响应体中返回错误描述。对于4xx代码,它必须包含足够的信息,以便客户端开发人员了解原因并修复客户端。出于安全原因,5xx不能透露任何细节。
  4. 如果客户端需要区分不同的错误,并根据它有不同的反应,定义一个机器可读的和可扩展的错误格式,并在你的API中到处使用它。从一开始就这样做是一个很好的实践。
  5. 请记住,客户端开发人员可能会做一些奇怪的事情,并试图解析你返回的字符串,作为人类可读的描述。通过更改字符串,您将破坏编写得如此糟糕的客户端。因此,始终提供机器可读的描述,并尽量避免以文本形式报告额外信息。

所以在你的情况下,我返回400错误和类似的东西,如果“罗曼”是从用户输入和客户端必须有特定的反应:

{
"error_type" : "unsupported_resource",
"error_description" : "\"Roman\" is not supported"
}

或者更一般的错误,如果这种情况是客户端的一个糟糕的逻辑错误,除非开发人员犯了错误:

{
"error_type" : "malformed_json",
"error_description" : "\"Roman\" is not supported for \"requestedResource\" field"
}

首先检查URL,它可能是错误的,如果是正确的,然后检查你正在发送的请求体,可能的原因是你正在发送的请求缺少正确的语法。

要详细说明,请检查请求字符串中的特殊字符。如果使用的是(特殊字符),则是此错误的根本原因。

尝试复制请求并分析每个标签数据。

作为补充,对于那些可能遇到与我相同问题的人,我使用$.ajax将表单数据发布到服务器,并且我一开始也得到了400错误。

假设我有一个javascript变量,

var formData = {
"name":"Gearon",
"hobby":"Be different"
};

不要直接使用变量formData作为键data的值,如下所示:

$.ajax({
type: "post",
dataType: "json",
url: "http://localhost/user/add",
contentType: "application/json",
data: formData,
success: function(data, textStatus){
alert("Data: " + data + "\nStatus: " + status);
}
});

相反,使用JSON。stringify封装formData,如下:

$.ajax({
type: "post",
dataType: "json",
url: "http://localhost/user/add",
contentType: "application/json",
data: JSON.stringify(formData),
success: function(data, textStatus){
alert("Data: " + data + "\nStatus: " + status);
}
});

无论如何,正如其他人所说明的那样,错误是因为服务器无法识别请求导致语法错误,我只是在实践中提出一个实例。希望对大家有所帮助。

这让我想起了和别人的对话,“我理解-我只是不同意”。

400表示服务器没有理解

200表示服务器完全理解并完全处理了请求。

当服务器返回200时,它在说,“我理解您的要求,我处理了它,没有意外错误,这是我的正确响应”。

200表示您可以信任响应中发送的答案。也许答案是“罗马人是不允许的”;-但它仍然是一个正确的答案,生成时没有任何意想不到的问题。

200没有表达关于预期错误或已处理异常的任何信息——因为这不是消息传输过程的一部分。这些是关于HTTP的状态代码,即传输本身的状态。

我认为模糊“交通/通讯”之间的界限;与“Processing"应该避免。

对于那些喜欢用HTTP代码来表示处理中的问题的人(“我不同意”;部分)似乎409冲突最适用于“罗马人不允许”
RFC 7231 409冲突 < / p >

冲突在很大程度上意味着“缺乏一致”;对吧?

无论您选择什么HTTP响应代码,似乎每个人都同意您的响应应该解释为什么失败,以及如何解决它。在罗曼的情况下,可能返回字段可接受的值列表?

在我的情况下,这意味着我在json中提供的数据与db所需的数据不兼容,例如电子邮件地址已经添加到db,然后抛出代码400