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

如果requestdresource字段存在,但“Roman”是这个字段的无效值,这应该被视为400吗?

[{requestedResource:"Roman"}] 

这应该被视为400的“blah”字段不存在吗?

[{blah:"Roman"}]

从w3.org

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


想想期望。

作为客户端应用程序,您希望知道服务器端是否出现了问题。如果服务器需要在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请求外,服务器应该发送一个 包含错误情况解释的陈述, 这是暂时的还是永久的。

规则如下:

If request was successful, then return 2xx code (3xx for redirect). If there was an internal logic error on a server, then return 5xx. If there is anything wrong in client request, then return 4xx code. Look through available response code from selected category. If one of them has a name which matches well to your situation, you can use it. Otherwise just fallback to x00 code (200, 400, 500). If you doubt, fallback to x00 code. Return error description in response body. For 4xx codes it must contain enough information for client developer to understand the reason and fix the client. For 5xx because of security reasons no details must be revealed. If client needs to distinguish different errors and have different reaction depending on it, define a machine readable and extendible error format and use it everywhere in your API. It is good practice to make that from very beginning. Keep in mind that client developer may do strange things and try to parse strings which you return as human readable description. And by changing the strings you will break such badly written clients. So always provide machine readable description and try to avoid reporting additional information in text.

所以在你的情况下,我返回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 post表单数据到服务器,我也得到了400错误在第一次。

假设我有一个javascript变量,

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

不要像下面这样直接使用变量formData作为关键数据的值:

$.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的状态代码,即传输本身的状态。

我认为应该避免模糊“运输/通信”和“处理”之间的界限。

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

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

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


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