我有一个 JSON 请求,我将其发布到 HTTP URL。
这是否应该被视为400
存在requestedResource
字段但"Roman"
该字段的值无效?
[{requestedResource:"Roman"}]
这应该被视为根本不存在字段吗400
?"blah"
[{blah:"Roman"}]
我有一个 JSON 请求,我将其发布到 HTTP URL。
这是否应该被视为400
存在requestedResource
字段但"Roman"
该字段的值无效?
[{requestedResource:"Roman"}]
这应该被视为根本不存在字段吗400
?"blah"
[{blah:"Roman"}]
400 表示请求格式不正确。也就是说,客户端向服务器发送的数据流不符合规则。
在带有 JSON 有效负载的 REST API 的情况下,根据服务的 API 规范,400 通常(并且我会说正确)用于指示 JSON 在某种程度上是无效的。
按照这个逻辑,你提供的两个场景都应该是 400 秒。
想象一下,这是 XML 而不是 JSON。在这两种情况下,XML 都不会通过模式验证——要么是因为未定义的元素,要么是因为不正确的元素值。那将是一个糟糕的要求。这里也是一样的。
来自w3.org
10.4.1 400 错误请求
由于语法错误,服务器无法理解该请求。客户端不应该在没有修改的情况下重复请求。
选择 HTTP 响应代码是一项非常简单的任务,可以通过简单的规则来描述。唯一经常被遗忘的棘手部分是 RFC 7231 的第 6.5 段:
除了响应 HEAD 请求时,服务器应该发送一个包含错误情况解释的表示,以及它是暂时的还是永久的条件。
规则如下:
因此,在您的情况下,如果从用户输入中获得“罗马”并且客户端必须有特定反应,我会返回 400 错误和类似的内容:
{
"error_type" : "unsupported_resource",
"error_description" : "\"Roman\" is not supported"
}
或更通用的错误,如果这种情况是客户端中的错误逻辑错误并且不是预期的,除非开发人员犯了错误:
{
"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,也将 HTTP 错误(如 400 和 500)视为大故障,要求程序员检测正在发生的事情并根据它是否是“真正的”错误进行分支。
将400
状态代码用于任何其他目的,而不是指示请求格式错误是完全错误的。
如果请求有效负载包含无法解析为的字节序列application/json
(如果服务器需要该数据格式),则相应的状态代码为415
:
服务器拒绝为请求提供服务,因为请求的实体采用所请求方法的请求资源不支持的格式。
422
如果请求负载在语法上正确但在语义上不正确,则可以使用非标准响应代码,或者标准403
状态代码:
服务器理解请求,但拒绝执行。授权将无济于事,并且不应重复请求。
想想期望。
作为客户端应用程序,您希望知道服务器端是否出现问题。如果服务器需要在blah
丢失或requestedResource
值不正确时抛出错误,那么 400 错误将是合适的。
首先检查可能是错误的 URL,如果正确则检查您发送的请求正文,可能的原因是您发送的请求缺少正确的语法。
要详细说明,请检查请求字符串中的特殊字符。如果使用的是(特殊字符),则这是此错误的根本原因。
尝试复制请求并分析每个标签数据。
作为补充,对于那些可能遇到与我相同的问题的人,我正在使用$.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);
}
});
无论如何,正如其他人所说明的那样,错误是因为服务器无法识别请求导致语法错误,我只是在实践中提出一个实例。希望对某人有所帮助。
这让我想起了与其他人的常见对话,“我明白 - 我只是不同意”
400 表示服务器不理解
200 表示服务器完全理解并完全处理了请求。
当服务器返回 200 时,它是在说,“我明白你的要求,我处理它没有意外错误,这是我的正确回应”
200 表示您可以信任响应中发送的答案。也许答案是“不允许罗马人” - 但它仍然是一个正确的答案,没有任何意想不到的问题。
200 不表达任何有关预期错误或已处理异常的信息 - 因为这不是消息传输过程的一部分。这些是关于 HTTP 的状态代码,即传输本身的状态。
我相信应该避免模糊“传输/通信”与“处理”之间的界限。
对于那些更喜欢 HTTP 代码来指示处理问题的人(“我不同意”部分),似乎 409 冲突最适用于“不允许罗马人”
RFC 7231 409 冲突
冲突几乎意味着“缺乏协议”,对吗?
无论您为 HTTP 响应代码选择什么,似乎每个人都同意您的响应应该解释为什么它失败,以及如何解决它。在 Roman 的情况下,也许返回该字段的可接受值列表?
就我而言,这意味着我在 json 中提供的数据与 db 所需的数据不兼容,例如电子邮件地址已添加到 db 中,然后它会抛出代码 400