364

我有一个 JSON 请求,我将其发布到 HTTP URL。

这是否应该被视为400存在requestedResource字段但"Roman"该字段的值无效?

[{requestedResource:"Roman"}] 

这应该被视为根本不存在字段吗400"blah"

[{blah:"Roman"}]
4

10 回答 10

378

400 表示请求格式不正确。也就是说,客户端向服务器发送的数据流不符合规则。

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

按照这个逻辑,你提供的两个场景都应该是 400 秒。

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

于 2013-10-30T00:09:29.880 回答
78

来自w3.org

10.4.1 400 错误请求

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

于 2013-10-29T23:52:56.113 回答
55

选择 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"
}
于 2016-09-22T17:40:15.893 回答
24

在这两种情况下,“语法格式错误”都没有。这是错误的语义。因此,恕我直言,400 是不合适的。相反,返回 200 以及某种错误对象(例如{ "error": { "message": "Unknown request keyword" } }或其他)是合适的。

考虑客户端处理路径。语法错误(例如无效的 JSON)是程序逻辑中的错误,换句话说,是某种错误,应该以类似于 403 的方式进行相应处理,例如;换句话说,有些不好的地方出了问题。

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

例如,在 jQuery 中,我宁愿不必编写单个错误处理程序来处理诸如 500 之类的事情和一些特定于应用程序的语义错误。其他框架,例如 Ember,也将 HTTP 错误(如 400 和 500)视为大故障,要求程序员检测正在发生的事情并根据它是否是“真正的”错误进行分支。

于 2014-07-07T12:10:58.090 回答
18

400状态代码用于任何其他目的,而不是指示请求格式错误是完全错误的。

如果请求有效负载包含无法解析为的字节序列application/json(如果服务器需要该数据格式),则相应的状态代码为415

服务器拒绝为请求提供服务,因为请求的实体采用所请求方法的请求资源不支持的格式。

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

服务器理解请求,但拒绝执行。授权将无济于事,并且不应重复请求。

于 2016-09-22T16:22:48.450 回答
9

想想期望。

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

于 2013-10-29T23:58:09.837 回答
7

首先检查可能是错误的 URL,如果正确则检查您发送的请求正文,可能的原因是您发送的请求缺少正确的语法。

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

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

于 2017-02-20T13:20:44.180 回答
6

作为补充,对于那些可能遇到与我相同的问题的人,我正在使用$.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); 
    }
});

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

于 2019-02-21T15:17:23.840 回答
2

这让我想起了与其他人的常见对话,“我明白 - 我只是不同意”

400 表示服务器不理解

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

当服务器返回 200 时,它是在说,“我明白你的要求,我处理它没有意外错误,这是我的正确回应”

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

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

我相信应该避免模糊“传输/通信”与“处理”之间的界限。

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

冲突几乎意味着“缺乏协议”,对吗?

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

于 2021-03-04T18:21:25.500 回答
0

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

于 2022-02-01T07:33:24.173 回答