ChatGPT解决这个技术问题 Extra ChatGPT

如果请求缺少必需的参数,我应该使用什么 HTTP 状态响应代码?

我在想 412(前提条件失败)但可能有更好的标准?

412肯定是错的

D
David Ongaro

基于 spec,状态 422 似乎最合适。

422(Unprocessable Entity)状态码意味着服务器理解请求实体的内容类型(因此 415(Unsupported Media Type)状态码是不合适的),并且请求实体的语法是正确的(因此是 400(Bad Request) ) 状态码不合适)但无法处理包含的指令。例如,如果 XML 请求正文包含格式正确(即语法正确)但语义错误的 XML 指令,则可能会出现这种错误情况。

他们指出格式错误的 xml 是错误语法的一个示例(要求 400)。格式错误的查询字符串似乎与此类似,因此 400 似乎不适合缺少参数的格式良好的查询字符串。

注意:由于上述 RFC 是关于 WebDAV 的,因此可能会产生一种误解,即 422 和其他一些内容只能在 WebDAV 的上下文中使用,并且在 WebDAV 之外使用它们是“非标准的”。但这仅意味着这些状态代码是在本 RFC 的上下文中引入的。事实上,这些定义的措辞是经过精心挑选的,并非特定于 WebDAV。


IMO 我会在查询字符串中的值不正确时使用它,而不是在有额外值或缺失值时使用它。 IE。期待一封电子邮件,其值为“123123”
我倾向于将 GET 和 POST 参数视为 URL 路径的方法签名,因此 404 对我来说很有意义。在用于公共消费的 RESTful API 中,返回缺失/额外参数是谨慎的做法。在 URL 的上下文中,查询字符串参数通常对于识别资源很重要,额外或缺失的参数表示不存在的资源,没有任何假设。当然,通过显式来权衡健壮性,可选参数使资源可能同样容易受到静默错误的影响。然后是可用性...
引用的规范适用于 WebDAV,而不是 HTTP 标准规范。
@DavidV您是正确的,它适用于WebDAV,但对于核心HTTP似乎没有更好的选择。 This blog 提到了使用 422 的流行 API。
这值得一读:bennadel.com/blog/… 我也不会使用 422 来丢失参数。我认为400更合适。
C
Community

我不确定是否有一套标准,但我会使用 400 Bad Request,这是最新的 HTTP 规范(从 2014 年开始)documents as follows

6.5.1. 400 Bad Request 400(Bad Request)状态码表示服务器不能或不会处理请求,因为某些被认为是客户端错误(例如,格式错误的请求语法、无效的请求消息帧或欺骗性请求路由) .


400 Bad Request 表示协议级别的问题,而不是语义错误。如果我们要劫持 HTTP 状态代码来指示应用程序级(而不是协议级)错误,为什么不一直使用 412 呢?
谷歌的 OAuth 1.0 实现同意这个答案。当 POST 参数丢失或不受支持时,会给出 400 响应:code.google.com/apis/accounts/docs/OAuth_ref.html
@matt-zukowski:“412:在服务器上测试时,一个或多个请求标头字段中给出的先决条件评估为假。”来自 RFC2616 - 如果是 POST,则参数在请求正文中,而不是在请求标头字段中。从技术上讲,GET 方法在请求标头中发送它的参数,但我宁愿有一些一致性?
@MattZukowski 400 是应用程序级别的状态代码。如果您查看 RFC 7231 草案版本中的重新措辞,您会看到这一点。不幸的是,最新版本中的措辞不是很清楚,因为最新更改的作者还发明了 422。
@DarrelMiller 是对的 (direct link):“400 (Bad Request) 状态代码表明服务器不能或不会处理请求,因为某些东西被认为是客户端错误(例如,格式错误的请求语法,无效的请求消息帧,或欺骗性的请求路由)。” 根据语义和可扩展性期望(有朝一日是否可以在没有参数的情况下发出请求?)然后在标准 HTTP 中似乎只有 400 和 404 是合适的。否则,为您的 API 发明新代码,但不要重载语义。
C
Community

.NET 中的 WCF API 在使用 webHttpBinding 时通过返回 HTTP 404“未找到端点”错误来处理丢失的参数。

如果您将 Web 服务方法名称连同其参数签名一起考虑,404 Not Found 会很有意义。也就是说,如果您公开一个 Web 服务方法 LoginUser(string, string) 并请求 LoginUser(string),则找不到后者。

基本上,这意味着您正在调用的 Web 服务方法以及您指定的参数签名无法找到。

10.4.5 404 Not Found 服务器没有找到任何匹配请求 URI 的东西。没有说明这种情况是暂时的还是永久性的。

400 Bad RequestGert suggested 一样,仍然是有效的响应代码,但我认为它通常用于指示较低级别的问题。它很容易被解释为格式错误的 HTTP 请求,可能是 HTTP 标头丢失或无效,或类似情况。

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


这就是 CherryPy 默认所做的。
在处理您接受模型并且模型的一部分丢失的发布请求时怎么办?在这种情况下,您不会得到 404。相反,如果我没记错的话,您会得到一个无效的模型,您必须决定现在做什么。
这种解释似乎有点牵强,表达的是 RPC 而不是 REST pov。 URI 是标识符,它存在并且已经被找到。正文中发送的内容不是资源标识符的一部分。 422更合适。
404是正确的答案,去网上编辑一些网址来寻找共识吧!
B
BoltClock

您可以发送 400 Bad Request 代码。它是更通用的 4xx 状态代码之一,因此您可以使用它来表示您的意图:客户端发送的请求缺少您的应用程序正确处理它所需的信息/参数。


E
Elad Meidar

如果所需参数中的某些内容与 API 端点所需的内容不匹配(例如密码太短),我通常会选择 422(无法处理的实体),但对于缺少的参数,我会选择 406(不可接受)。


好吧,406 Unacceptable 与 Accept 标头一起使用(如果服务器无法发送响应,客户端将理解)。 “请求标识的资源只能生成响应实体,其内容特征根据请求中发送的接受标头不可接受。” .我坚持使用 422,因为当前规范没有“正确”选择:-/
为此使用 406 是错误的。 406 代码并不意味着 request 不可接受;这意味着您无法满足请求,因为您能够提供的响应是 client 根据它在请求中发送的 Accept 标头会发现不可接受的响应。 (例如,请求包含 Accept-Language: de,表示它只接受德语响应,但您的服务器可用的请求文档的唯一版本是英语或法语。)使用它来表示请求中缺少参数不正确,根据规范中的定义。
g
gabrielem

在我们的一个 API 项目中,我们决定为某个请求设置 409 状态,因为缺少参数,我们无法以 100% 完全填充它。

HTTP 状态代码“409 冲突”对我们来说是一个很好的尝试,因为它的定义要求包含足够的信息让用户识别冲突的来源。

参考:w3.org/Protocols/

因此,在 400 或 404 等其他响应中,我们选择了 409 来强制查看请求中的一些注释,这有助于建立一个新的和正确的请求。

无论如何,我们的案例都是特殊的,因为如果请求不完全正确,我们需要在前夕发送一些数据,并且我们需要强制客户端查看消息并了解请求中的错误。

一般来说,如果我们只有一些缺失参数,我们会选择 400 和一组缺失参数。但是当我们需要发送更多信息时,例如特定案例消息,并且我们希望更确定客户会处理它,我们发送 409


这是完全错误的。 409 用于并发问题,因为@MaximeGélinas 指出了资源已经存在并且不允许重复的情况。
根据规范,“409(冲突)状态代码表示由于与目标资源的当前状态冲突而无法完成请求。”。将它用于缺少的参数是错误的;这是一种完全不同的错误。
N
Neromancer

对于那些感兴趣的人,Spring MVC(至少 3.x)在这种情况下返回 400,这对我来说似乎是错误的。

我测试了几个 Google URL (accounts.google.com) 并删除了必需的参数,在这种情况下它们通常返回 404。

我会复制谷歌。


因为谷歌这样做并不自动意味着谷歌做得对!
我同意,不一定是“正确的”,但有时正确和明智是两件不同的事情。无论如何..取决于读者:)
某些 Google API 返回 400,例如 github.com/google/google-api-nodejs-client/issues/404
这是错误的(以及为什么 spring mvc 不兼容 jax-rs)
L
Luca

可以说应该使用 404 Not Found,因为找不到指定的资源。


当查询参数无法转换为正确的数据类型时,这是 Java JAX-RS 的默认行为。不过我不同意。找到了资源:查询参数用于过滤资源,其中一个过滤器提供了不可接受的值。我认为这与最接近的 422 Unprocessable Entity 和最接近的 400 Bad Request 匹配。
它是 jax-rs 的默认行为,因为它是正确的行为!
当查询字符串参数用于标识资源时,使用 404 是合理的,给出了一个值,但该值与存在的资源不对应 - 例如,如果您请求 example.com/show-user-profile?user_id=123 而用户 123 没有不存在。但这不是这个问题要问的;这是关于完全省略必需参数的情况。我看不出这与未找到的指定资源有何对应。
C
Community

我经常使用 403 Forbidden 错误。理由是请求被理解,但我不会按要求去做(因为事情是错误的)。响应实体解释了问题所在,因此如果响应是 HTML 页面,则错误消息在页面中。如果是 JSON 或 XML 响应,则错误信息就在其中。

rfc2616

10.4.4 403 Forbidden 服务器理解请求,但拒绝执行。授权将无济于事,并且不应重复请求。如果请求方法不是 HEAD 并且服务器希望公开请求未完成的原因,它应该在实体中描述拒绝的原因。如果服务器不希望向客户端提供此信息,则可以使用状态代码 404(未找到)来代替。


最初听起来不错,尽管我自然会将其与基于身份验证或权限的错误相关联。此外,规范暗示了这一点,它说“如果服务器不希望将这些信息提供给客户端”。此外,404 可能是一个更好的选择。我会选择 404 或 400,而不是 403。
这是一个糟糕的想法,即使在技术上是合理的。 403 普遍用于身份验证失败响应,如果您尝试使用它来指示参数错误,您将把您的客户搞糊涂。例如,Twitter 会这样做——当你提供无效的 OAuth 凭据时,以及当你的请求出现语义错误时,都会使用 403——这对于 API 客户端来说是一个持续的混淆来源。
@MattZukowski 好吧,那是错误的。规范说 Authorization will not help,因此 Twitter 不应发送此信息以获得无效的 OAuth 凭据。
@torvin Twitter 应该改为发送 401 Unauthorized。但是,如果您查看这两个非常相似的代码中的 the MDN docs' descriptions,您就会明白为什么它们不这样做。
您应该在回复中描述失败的原因。如果您不想这样做,只需使用 404。