正确的 HTTP 状态码到错误的输入
Posted
技术标签:
【中文标题】正确的 HTTP 状态码到错误的输入【英文标题】:What HTTP status code should be used for wrong input 【发布时间】:2011-12-17 20:33:27 【问题描述】:当不报告 200(一切正常)但输入错误时,最佳 HTTP 响应代码是什么?
比如,你向服务器提交了一些数据,它会响应你的数据是错误的
使用500
看起来更像是服务器问题
使用带有警告/错误响应文本的 200
是错误的(允许缓存并且一切都不正常)
使用 204
并且什么也不返回,这可能很好(但得到很好的支持?)
如果请求的路径(脚本)可用且在适当的位置,则使用 404
是错误的
【问题讨论】:
详情见我的回答***.com/a/59527615/4127230 【参考方案1】:我们在制作 API 时也遇到了同样的问题。我们正在寻找与InvalidArgumentException
等效的HTTP 状态代码。在阅读了下面的源文章后,我们最终使用了422 Unprocessable Entity
,其中指出:
422(Unprocessable Entity)状态码意味着服务器理解请求实体的内容类型(因此 415(Unsupported Media Type)状态码是不合适的),并且请求实体的语法是正确的(因此 400 (错误请求)状态代码不合适)但无法处理包含的指令。例如,如果 XML 请求正文包含格式正确(即语法正确)但语义错误的 XML 指令,则可能会发生这种错误情况。
来源:https://www.bennadel.com/blog/2434-http-status-codes-for-invalid-data-400-vs-422.htm
【讨论】:
【参考方案2】:以 4 (4xx) 开头的代码表示客户端错误。也许 400 (Bad Request) 可能适合这种情况? http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 中的定义说:
“由于语法错误,服务器无法理解请求。客户端不应该不加修改地重复请求。”
【讨论】:
400 Bad Request
不错,但通常应保留用于格式错误的语法。 OP 似乎更关心语法格式正确但值无效的情况。 Plus 400 是一个相当常见的“哦,该死的东西不对”响应代码,您可能希望将其与错误输入的特定情况区分开来。
请注意,RFC 7231 中的措辞已更新,并且“由于语法错误,服务器无法理解请求”已更新为“服务器无法或不会处理请求,因为被认为是客户端错误的东西(例如,格式错误的请求语法、无效的请求消息帧或欺骗性请求路由)”。【参考方案3】:
409 Conflict
可能是一个可接受的解决方案。
根据:https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
由于与资源的当前状态冲突,请求无法完成。仅在预期用户可能能够解决冲突并重新提交请求的情况下才允许使用此代码。响应正文应该包含足够的信息让用户识别冲突的来源。理想情况下,响应实体将包含足够的信息供用户或用户代理解决问题;但是,这可能是不可能的,也不是必需的。
文档继续举例:
在响应 PUT 请求时最有可能发生冲突。例如,如果正在使用版本控制并且被 PUT 的实体包括对资源的更改,这些更改与早期(第三方)请求所做的更改相冲突,则服务器可能会使用 409 响应来指示它无法完成请求.在这种情况下,响应实体可能会以响应 Content-Type 定义的格式包含两个版本之间差异的列表。
就我而言,我想通过 API 将一个必须唯一的字符串放入数据库。在将它添加到数据库之前,我正在检查它是否已经在数据库中。
如果是,我会回"Error: The string is already in the database", 409
。
我相信这就是 OP 想要的:适用于数据未通过服务器标准时的错误代码。
【讨论】:
【参考方案4】:根据下面的场景,
假设有人使用正确格式的数据向您的服务器发出请求,但根本不是“好”数据。例如,假设有人将 String 值发布到期望 String 值的 API 端点;但是,字符串的值包含被列入黑名单的数据(例如,阻止人们使用“密码”作为他们的密码)。那么状态码可以是 400 还是 422 呢?
到目前为止,我会返回一个“400 Bad Request”,根据 w3.org 的说法,这意味着:
由于格式错误,服务器无法理解请求 句法。客户端不应该重复请求 修改。
这个描述不太符合实际情况;但是,如果您查看 HTTP/1.1 协议中定义的核心 HTTP 状态代码列表,这可能是您最好的选择。
然而,最近,我的开发团队中有人 [向我] 指出,流行的 API 开始使用 HTTP 扩展来更精细地报告错误。具体来说,许多 API,如 Twitter 和 Recurly,都使用 WebDAV 的 HTTP 扩展中定义的状态代码“422 Unprocessable Entity”。 HTTP 状态码 422 状态:
422 (Unprocessable Entity) 状态码表示服务器 理解请求实体的内容类型(因此是 415 (不支持的媒体类型)状态码不合适),以及语法 请求实体的正确(因此是 400(错误请求)状态代码 不合适)但无法处理包含的 指示。例如,如果 XML 请求正文包含格式正确(即语法正确),但是 语义错误的 XML 指令。
回到上面的密码示例,这个 422 状态码感觉更合适。服务器了解您要执行的操作;它了解您提交的数据;它根本不会处理这些数据。
【讨论】:
【参考方案5】:404 - Not Found - 可用于请求的 URI 无效或请求的资源(例如用户)不存在。
【讨论】:
OP 已经排除:“使用 404 是错误的,如果请求的路径(脚本)可用并且在适当的位置”以上是关于正确的 HTTP 状态码到错误的输入的主要内容,如果未能解决你的问题,请参考以下文章