关于rest:400 BAD请求HTTP错误代码含义?

400 BAD request HTTP error code meaning?

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

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

1
[{requestedResource:"Roman"}]

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

1
[{blah:"Roman"}]


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

对于具有JSON有效负载的REST API,通常我会说400,根据服务的API规范,以某种方式表示JSON无效。

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

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


来自w3.org

10.4.1 400 Bad Request

The request could not be understood by the server due to malformed
syntax. The client SHOULD NOT repeat the request without
modifications.


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

Except when responding to a HEAD request, the server SHOULD send a
representation containing an explanation of the error situation,
and whether it is a temporary or permanent condition.

规则如下:

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

    1
    2
    3
    4
    {
       "error_type" :"unsupported_resource",
       "error_description" :""Roman" is not supported"
    }

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

    1
    2
    3
    4
    {
       "error_type" :"malformed_json",
       "error_description" :""Roman" is not supported for "requestedResource" field"
    }

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

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

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

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


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

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

    The server is refusing to service the request because the entity of
    the request is in a format not supported by the requested resource for
    the requested method.

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

    The server understood the request, but is refusing to fulfill it.
    Authorization will not help and the request SHOULD NOT be repeated.


    想想期望。

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


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

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

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


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

    假设我有一个javascript变量,

    1
    2
    3
    4
                var formData = {
                   "name":"Gearon",
                   "hobby":"Be different"
                    };

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
                $.ajax({
                    type:"post",
                    dataType:"json",
                    url:"http://localhost/user/add",
                    contentType:"application/json",
                    data: formData,
                    success: function(data, textStatus){
                        alert("Data:" + data +"
    Status:" + status);
                    }
                });

    相反,使用JSON.stringify封装formData,如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
                $.ajax({
                    type:"post",
                    dataType:"json",
                    url:"http://localhost/user/add",
                    contentType:"application/json",
                    data: JSON.stringify(formData),
                    success: function(data, textStatus){
                        alert("Data:" + data +"
    Status:" + status);
                    }
                });

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