400 BAD请求HTTP错误代码的含义?


345

我有一个要发布到HTTP URL的JSON请求。

如果这被视为400其中requestedResource场存在,但"Roman"对于这方面的无效值?

[{requestedResource:"Roman"}] 

应该将其视为根本不存在字段的400地方"blah"吗?

[{blah:"Roman"}]

34
也许是402,如果他们真的希望能够发送该值Roman
则只

我看到的一个真实场景-我进行了PUT调用以添加一些数据。我再次使用相同的请求正文进行了一次put调用,并得到一个400,告诉我先前的请求已在处理中。对于我们的系统来说,花些时间来添加数据是正常的。
MasterJoe2

Answers:


360

400表示请求格式错误。换句话说,客户端发送到服务器的数据流不遵循规则。

对于具有JSON有效负载的REST API,通常,并且我会正确地说,根据服务的API规范,通常使用400来表示JSON无效。

按照这种逻辑,您提供的两个方案都应为400。

想象一下,这是XML而不是JSON。在这两种情况下,XML都永远不会通过架构验证-由于未定义元素或元素值不正确。那将是一个糟糕的要求。同样的交易。


3
我同意您的观点,“按照这种逻辑,您提供的两个方案都应该是400个。” 我认为JSON的内容在这里不重要。当你说畸形我愿意相信,来解决上述问题在你发送的数据的格式,例如,如果你跳过了某个领域的JSON你应该得到400
Geethanga

2
restapitutorial.com/httpstatuscodes.html上有一组不错的REST响应代码。它还可能取决于您要如何处理有效的请求,例如不允许的406(不可接受)或405方法。但是,400是适当的,因为“由于语法格式错误,服务器无法理解该请求。未经修改,客户端不应重复该请求。”
Andrew Scott Evans

3
因此,“由于语法错误,服务器无法理解该请求”可以是该请求(例如,一个HTTP标头之一格式错误)或该请求所携带的数据(例如,缺少JSON值) ?
MC皇帝

2
Vidya说“ XML永远不会通过模式验证”。关键是XML解析器区分格式正确的文档(即,语法上合理)和有效的文档(例如,根据架构在语义上合理)。400代码的描述是“由于语法格式不正确,服务器无法理解该请求”-因此,不应将其用于验证错误,恕我直言。
Martin Lie

@Vidya stackoverflow.com/questions/42851301/...如果你知道,请帮我看看这个错误我也面临着类似这样的错误同样的问题
磨憨戈皮

74

来自w3.org

10.4.1 400错误的请求

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


10
返回错误400的正确性不是基于字段还是值,而是整个请求。我认为HTTP 400是一个不错的选择
Jason Sperske

您是说要使用400响应来告诉客户请求中的任何内容(例如url,标头,正文等)都是错误的,而不仅仅是正文?
MasterJoe2

3
对于url,正确的代码是404,对于标头,我想这是一个折腾,如果标头拒绝标识,403(禁止)似乎是正确的方法,但是如果标头确定输出格式怎么办?我认为400唯一正确的选择是在请求采取的行动没有道理并且不应重复的情况下。我在4年前写了这个答案,如今,我觉得即使错误也应返回200,并且该错误应仅适用于http传输,而不适用于有效负载。
杰森·斯珀斯凯

1
这个答案涵盖了很多内容,尽管我还没有阅读所有图表,但是stackoverflow.com/a/34324179/16959
Jason Sperske

@JasonSperske负载平衡器,代理和其他中间件经常使用状态码来帮助路由,报告和维修。幸运的是,像“ 422”这样的代码明确地涉及有效负载,因此规范中对于有效负载状态代码有一定的余地。
Erik Aronesty '19

53

选择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"
}

21

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

考虑客户端处理路径。语法错误(例如无效的JSON)是程序逻辑中的错误,换句话说是某种错误,应按照类似于403的方式进行相应的处理;例如:换句话说,坏事出了错。

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

例如,在jQuery中,我希望不必编写处理500之类的错误处理程序和某些特定于应用程序的语义错误的错误处理程序。其他框架,例如Ember,也将400s和500s之类的HTTP错误等同地视为大错误,要求程序员检测正在发生的事情并根据是否是“实际”错误进行分支。


4
+ 1,HTTP中的P代表协议,如果响应是HTTP错误,则应该是一个低级问题。多年来,我使用torazaburo描述的方法避免了很多代码复杂性。如果我们所有人都编写弹性代码,而不是那么频繁地因HTTP错误而崩溃,那么在REST领域的痛苦就会减轻。
Dem Pilafian '16

25
200表示请求已处理,因此应在客户端上执行正常的成功逻辑。这里我们肯定有一个错误,所以响应不能有2xx或3xx代码。也不能是5xx,因为那是服务器端错误,而我们在客户端端有错误。所以那一定是4xx错误。但是响应正文中的错误描述是正确的做法,实际上是HTTP规范建议的一种方式。
Alexey Guseynov

422更好,适用于记录器,代理和其他工具
Erik Aronesty

16

400状态代码用于指示请求以外的其他目的的格式不正确是完全错误的。

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

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

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

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


3
没有,415是当实体声称是错误类型例如用于image/gif代替text/jsonContent-Type:报头中。-如果multipart的组件指定了错误的类型,那么这大概也适用,请参见tools.ietf.org/html/rfc4918,其中讨论了422,以进行更多讨论,
Jasen

8

考虑期望。

作为客户端应用程序,您希望知道服务器端是否出了问题。如果服务器在blah丢失或requestedResource值不正确时需要引发错误,则应选择400错误。


4

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

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

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


我收到http 400错误,我检查了我的请求是否有一些特殊字符。为了解决这个问题,我在内容类型中传递了charset = UTF-8。
Kislay Kishore

4

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.