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


Answers:


387

根据规范,状态422最合适。

422(不可处理实体)状态代码表示服务器理解请求实体的内容类型(因此415(不支持的媒体类型)状态代码不合适),并且请求实体的语法正确(因此400(错误请求) )状态代码不合适),但无法处理其中的说明。例如,如果XML请求主体包含格式正确(即,语法正确)但语义错误的XML指令,则可能发生此错误情况。

他们指出,格式错误的xml是语法错误的示例(要求400)。格式错误的查询字符串似乎与此相似,因此400似乎不适用于缺少参数的格式正确的查询字符串。

UPDATE @DavidV正确地指出此规范适用于WebDAV,而不适用于核心HTTP。但是,由于缺少更好的状态代码,一些流行的非WebDAV API仍在使用422(请参阅参考资料)。


2
IMO我将在查询字符串中的值不正确时使用它,而不是在存在额外值或缺少值时使用它。即。期待电子邮件和它的值是“123123”
德里克·利兹

2
我倾向于将GET和POST参数视为URL路径的方法签名,因此404对我来说很有意义。在供公众使用的RESTful API中,谨慎地返回missing / extra参数。在URL的上下文中,查询字符串参数通常对于标识资源很重要,多余或缺失的参数表示不存在的资源,没有任何假设。当然,通过显式进行健壮性需要权衡取舍,而可选参数使资源可能同样容易受到静默错误的影响。然后就是可用性...
Derek Litz 2013年

13
引用的规范适用于WebDAV,而不是HTTP标准规范。
大卫五世

1
@Kelvin感谢您指出该博客文章。例如,看到Twitter正在使用422会很有帮助。我认为,如果您在第一行中将规范指定为WebDAV,答案可能会更好。当我第一次阅读您的答案时,我以为您是在遵循链接之前指的是HTTP标准规范。
David V

3
值得一读:bennadel.com/blog/…我也不会使用422来缺少参数。我认为400比较合适。
Zelphir Kaltstahl '17

184

我不确定是否有设定的标准,但是我会使用400 Bad Request,最新的HTTP规范(来自2014年)记录如下

6.5.1。400错误的要求

400(错误请求)状态代码表示服务器由于某些原因(例如格式错误的请求语法,无效的请求消息框架或欺骗性的请求路由)而被视为客户端错误,因此服务器无法处理该请求。


65
400 Bad Request表示协议级别的问题,而不是语义错误。如果我们要劫持HTTP状态代码以指示应用程序级别(而不是协议级别)的错误,为什么不一直使用并直接使用412
Matt Zukowski

36
Google的OAuth 1.0实施方案对此答案表示同意。A 400给出响应时POST参数丢失或不支持:code.google.com/apis/accounts/docs/OAuth_ref.html
汤姆

1
@ matt-zukowski:“ 412:在服务器上测试时,在一个或多个请求标头字段中给出的前提条件被评估为false。” 从RFC2616开始 -如果它是POST,则参数在请求正文中,而不是在请求标头字段中。从技术上讲,GET方法在请求标头中发送其参数,但我宁愿具有一些一致性?
2012年

6
@MattZukowski 400是应用程序级别的状态码。如果您查看RFC 7231草案中的重新措词,您会看到。不幸的是,在最新版本的措辞不那么清楚,因为最新的变化笔者还发明422
达雷尔-米勒

9
@DarrelMiller是正确的(直接链接):“ 400(错误请求)状态代码表示服务器由于某些被视为客户端错误的原因(例如,格式错误的请求语法,无效的请求消息)而无法或不会处理该请求框架或欺骗性请求路由)。” 根据语义和可扩展性期望(是否有一天可以在不使用参数的情况下发出请求?),那么在标准HTTP中似乎只有400和404是合适的。否则,为您的API发明一个新代码,但不要重载语义。
tne

31

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

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

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

10.4.5找不到404

服务器未找到与请求URI匹配的任何内容。没有迹象表明这种情况是暂时的还是永久的。

400 Bad Request,因为格特建议,仍然是一个有效的响应代码,但我认为这是通常用于指示下级的问题。很容易将其解释为格式错误的HTTP请求,可能缺少或无效的HTTP标头或类似的内容。

10.4.1 400错误的请求

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


这就是CherryPy的默认设置。
德里克·里兹

当您在接受模型且缺少模型的一部分的情况下处理发布请求时,该怎么办?在这种情况下,您不会得到404。相反,如果我没记错的话,您将得到无效的模型,您必须决定现在要做什么。
Shane Courtrille 2015年

1
这种解释似乎是一种延伸,它表示的是RPC而不是REST pov。URI是标识符,它存在并且已经找到。正文中发送的内容不属于资源标识符。422更合适。
乔纳

404是正确的答案,只需在网络上编辑一些URL即可找到共识!
jenson-button-event

8

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


7

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

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

参考:w3.org/Protocols/

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

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

通常,如果我们只有一些缺失的参数,我们可以选择400和缺失参数的数组。但是,当我们需要发送更多信息(例如特殊情况的消息)并且希望确保客户会妥善处理时,我们发送409


2
这是完全错误的。409用于并发问题,因为@MaximeGélinas指出OR情况,即资源已经存在并且不允许重复。
gimlichael

按照规范,“ 409(冲突)状态代码表示由于与目标资源的当前状态冲突而无法完成请求。” 。使用它作为缺少的参数是错误的;那是完全不同的错误。
Mark Amery

5

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


8
好吧,406 Unacceptable与Accept标头一起使用(如果服务器无法发送客户端将理解的响应)。“由请求标识的资源仅能够生成响应实体,该响应实体具有根据请求中发送的接受标头不可接受的内容特征。” 。我坚持使用422,因为当前规范没有“正确”的选择:-/
JakubKnejzlik 2014年

为此使用406是错误的。406代码并不意味着该请求是不可接受的。这意味着您无法满足请求,因为根据请求中发送的Accept标头,您可以提供的响应是客户端认为不可接受的响应。(例如,包含的请求Accept-Language: de表示将仅接受德语响应,但服务器可用的被请求文档的唯一版本是英语或法语。)使用它来指示请求中缺少参数是不正确的,根据规范中的定义。
Mark Amery

3

对于那些感兴趣的人,在这种情况下,Spring MVC(至少3.x)返回400。

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

我会复制Google。


18
因为Google这样做并不意味着Google正确!
rve

4
我同意,不一定是“正确的”,但有时候正确和明智的是两件事。无论如何..取决于读者:)
Neromancer 2013年


这是错误的(以及为什么spring mvc不兼容jax-rs)
jenson-button-event

3

可能会争辩说404 Not Found应该使用a,因为找不到指定的资源。


3
当查询参数无法转换为正确的数据类型时,这是Java JAX-RS的默认行为。我不同意。已找到资源:查询参数用于过滤资源,并且为其中一个过滤器提供了不可接受的值。我认为这与最接近的422个不可处理实体和第二个最接近的400错误请求匹配。
Ryan

这是jax-rs的默认行为,因为它的行为正确!
jenson-button-event

当查询字符串参数用于标识资源时,使用404是合理的,它给出了一个值,但该值与存在的资源不对应-例如,如果您请求example.com/show-user -profile?user_id = 123,并且用户123不存在。但这不是这个问题要问的。这是关于完全省略必需参数的情况。我看不到如何对应找不到指定的资源。
Mark Amery

2

我经常使用403禁止错误。原因是请求已被理解,但我不会按照要求执行(因为事情有误)。响应实体说明了问题所在,因此,如果响应是HTML页面,则错误消息在该页面中。如果是JSON或XML响应,则其中包含错误信息。

rfc2616

10.4.4 403禁止

服务器理解了该请求,但拒绝执行该请求。
授权将无济于事,并且不应重复该请求。
如果请求方法不是HEAD,并且服务器希望
公开为什么未满足请求,则应在实体中描述拒绝的原因。如果服务器不希望将此信息提供给客户端,则
可以改用状态代码404 (未找到)。


4
最初听起来不错,尽管我自然会将其与身份验证或基于权限的错误相关联。同样,规范在此提示“如果服务器不希望将此信息提供给客户端”。同样,404可能是一个更好的选择。我头向404或400比403
tonyhb

21
即使从技术上讲,这也是一个可怕的想法。403通常用于身份验证失败响应,如果尝试使用403来指示参数错误,则会使客户端感到困惑。例如,Twitter做到了这一点-当您提供无效的OAuth凭据以及您的请求在语义上有误时,都会使用403-这是API客户端经常感到困惑的原因。
Matt Zukowski

1
@MattZukowski好吧,那是错误的。规格说明为Authorization will not help,因此Twitter不应将其发送给无效的OAuth凭据。
torvin

@torvin Twitter应该发送一个401 Unauthorized代替。但是,如果您查看MDN文档对这两个代码的描述,它们很相似,那么您会理解为什么它们不这样做。
Agi Hammerthief,

-1

仅使用ASP.NET Core作为参考或示例,ASP.NET Core即可为您提供带有操作的控制器,这就是“ Details”操作的外观。

    // GET: Cars/Details/5
    public async Task<IActionResult> Details(int? id)
    {
        if (id == null)
        {
            return NotFound();
        }

        var car = await _context.Cars.FirstOrDefaultAsync(m => m.CarId == id);
        if (car == null)
        {
            return NotFound();
        }

        return View(car);
    }

如果id未设置参数,则返回404 Not Found。


-5

返回404-表示找不到资源。

尝试编辑包含ID的网站的网址。我尝试了一些:

  • gitub回购问题
  • 汇合页面
  • 亚马逊产品视图
  • 易趣上市
  • 英国广播公司新闻文章

所有人都返回404,imo,因为这些开发人员正确地解释了标准,而这里的答案以及其他很多答案都没有!


1
我相信大多数开发人员都将“参数”定义为查询字符串或表单POST正文中的名称/值对之一。Github仓库发出的请求不包含此请求。
开尔文

@Kelvin我们的开发人员还在列表中包括路径参数。如果ANY url参数是必需的,表示资源的位置并且不包括在内,则应返回404。不包括requestBody
jenson-button-event

-6

我会选择403。

RFC 2616-超文本传输​​协议-HTTP / 1.1

403禁止

服务器理解了该请求,但拒绝执行该请求。授权将无济于事,并且不应重复该请求。如果请求方法不是HEAD,并且服务器希望公开为什么未满足请求,则应在实体中描述拒绝的原因。如果服务器不希望将此信息提供给客户端,则可以改用状态代码404(未找到)。

您应在回复中说明失败的原因。如果您不想这样做,请使用404。


3
不赞成投票,因为这是重复的答案。考虑将您的最新句子添加为较旧答案的注释,该答案提供使用403的功能
用户
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.