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

Pho*_*nix 335 rest error-handling http http-status-code-400

我有一个JSON请求,我发布到HTTP URL.

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

[{requestedResource:"Roman"}] 
Run Code Online (Sandbox Code Playgroud)

如果这被视为400其中"blah"场完全不存在吗?

[{blah:"Roman"}]
Run Code Online (Sandbox Code Playgroud)

Vid*_*dya 348

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

在具有JSON有效负载的REST API的情况下,通常我会说400,用于表示JSON根据服务的API规范以某种方式无效.

根据这个逻辑,你提供的两个场景都应该是400.

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

  • 我同意你的观点"按照这种逻辑,你提供的两种情景都应该是400.." 我认为JSON的内容在这里不重要.如果您说格式错误,我想相信以您发送的数据格式解决问题,例如,如果您跳过JSON中的字段,则应该获得400. (3认同)
  • 所以*"由于语法格式错误,服务器无法理解请求"*可以是**请求**(例如,其中一个HTTP标头格式错误)或**数据**由请求(例如,缺少JSON值)? (3认同)
  • http://www.restapitutorial.com/httpstatuscodes.html上有一组不错的REST响应代码.它还可能取决于您希望如何处理有效请求,例如406(不可接受)或405方法不允许.但是,400是合适的,因为"由于语法错误,服务器无法理解请求.客户端不应该在没有修改的情况下重复请求." (2认同)
  • Vidya说"XML永远不会通过架构验证".重点在于XML解析器区分文档格式良好(即语法合理)和有效(即语义合理,例如根据模式).400代码的描述是"由于格式错误*语法*,服务器无法理解请求" - 所以它不应该用于验证错误,imho. (2认同)

Jas*_*ske 71

来自w3.org

10.4.1 400错误请求

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

  • 返回错误400的正确性不是基于字段与值,而是基于整个请求.我认为HTTP 400是一个很好的方法 (10认同)
  • 好吧为url正确的代码是404,对于标题,我猜它是一个折腾,403(禁止)似乎是正确的方法去标头拒绝身份,但如果标题是确定输出格式怎么办?关于我认为适合400的唯一途径是在要求行动没有意义且不应重复的情况下.我在4年前写过这个答案,这些天我觉得甚至错误应该返回200,并且错误应该只适用于http传输而不是有效负载. (2认同)

Ale*_*nov 50

选择HTTP响应代码是一项非常容易的任务,可以通过简单的规则来描述.经常被遗忘的唯一棘手的部分是来自RFC 7231的第6.5段:

除了在响应HEAD请求时,服务器应该发送一个表示,其中包含错误情况的解释,以及它是暂时的还是永久的.

规则如下:

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

所以在你的情况下,如果从用户输入获得"Roman"并且客户端必须有特定的反应,我会返回400错误和类似的东西:

{
    "error_type" : "unsupported_resource",
    "error_description" : "\"Roman\" is not supported"
}
Run Code Online (Sandbox Code Playgroud)

或者更通用的错误,如果这种情况在客户端中是一个错误的逻辑错误而且不是预期的,除非开发人员犯了错误:

{
    "error_type" : "malformed_json",
    "error_description" : "\"Roman\" is not supported for \"requestedResource\" field"
}
Run Code Online (Sandbox Code Playgroud)


小智 20

在任何情况下都不是"语法格式错误".这是错误的语义.因此,恕我直言400是不合适的.相反,将200与某种错误对象(例如{ "error": { "message": "Unknown request keyword" } }或其他)一起返回是合适的.

考虑客户端处理路径.在语法错误(例如无效JSON)是在该程序的逻辑错误,换句话说某种错误,并且应当进行相应的处理,以类似于403的方式,说; 换句话说,坏事出了问题.

另一方面,参数值中的错误是语义错误,可能是由于用户输入验证不佳.它不是HTTP错误(虽然我认为它可能是422).处理路径会有所不同.

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

  • 200表示已处理请求,因此应在客户端上执行正常的成功逻辑.这里我们肯定有一个错误,所以响应不能有2xx或3xx代码.它不能是5xx,因为这是服务器端错误,我们在客户端有错误.所以这必须是4xx错误.但是响应正文中的错误描述是正确的,并且实际上是HTTP规范建议的方式. (25认同)
  • +1,HTTP中的**P**代表**协议**,如果响应是HTTP错误,则应该是低级问题.多年来,我使用torazaburo描述的方法避免了很多代码复杂性.如果我们都编写了*弹性*代码而不是经常爆发HTTP错误,那么REST领域的痛苦就会减少. (4认同)

Coc*_*sin 14

400状态代码用于除指示请求格式错误之外的任何其他目的都是完全错误的.

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

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

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

服务器理解请求,但拒绝履行请求.授权无效,请求不应重复.

  • 不,415用于声明实体的类型错误,例如`image/gif`而不是`Content-Type:`标题中的`text/json`. - 如果多部分的组件指定了错误的类型,可能这也适用,请参阅https://tools.ietf.org/html/rfc4918,其中讨论了422以进行更多讨论, (3认同)

小智 8

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

400表示服务器不理解

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

当服务器返回 200 时,它表示:“我理解您的要求,我处理它时没有出现意外错误,这是我的正确响应”

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

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

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

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

冲突几乎意味着“缺乏共识”,对吗?

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


fil*_*m42 7

想想期望.

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


Ank*_*ani 7

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

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

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


Eug*_*ene 6

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

假设我有一个 javascript 变量,

var formData = {
    "name":"Gearon",
    "hobby":"Be different"
    }; 
Run Code Online (Sandbox Code Playgroud)

不要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); 
    }
});
Run Code Online (Sandbox Code Playgroud)

相反,使用 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); 
    }
});
Run Code Online (Sandbox Code Playgroud)

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