错误“您所在地区不可用”的http状态代码应该是什么?


51

我们的服务目前在5个城市。如果有人尝试从其他任何城市调用我们的服务API,我们都将抛出此错误Service not available in your area

问题是,针对此错误的合适的http代码是什么?

  • 503服务不可用
  • 403:禁止

或者是其他东西?


52
“如果有人试图从任何其他城市调用我们的服务API”,请注意IP地理定位通常是错误的,如果您禁止IP地理定位到其他城市的任何用户,则很可能会将合法用户拒之门外。
格林

43
我是否不能为我的孩子叫车而来,我的孩子在另一个城市,需要到机场来探望我?
达伍德·伊本·卡里姆

29
虽然不是问题的答案,但HTTP 451(RFC 7725)可能对以后发现此问题的读者有用。其主要目的是表明由于法律要求,诉讼或限制(版权,法院命令等)而导致内容不可用
Tyzoid

34
如果网络连接,身份验证,应用程序内部没有错误以及语法上有效的输入都没有问题,则不应显示错误消息。有了“我们不在此领域提供服务”,您就离开了技术问题,而涉足业务问题,因此我不确定HTTP错误是否合适。我认为您应该给200和(或302并重定向到)一条适当的消息,关于“抱歉我们的服务在您所在的地区尚不可用-但是我们正在扩展-请在2019年末检查!” 或任何营销部门提出的建议。
ivanivan

7
从这个问题尚不清楚,您是否要基于客户端计算机的位置(地理位置IP?)阻止对API的所有访问,还是要询问特定失败的API请求的响应代码(例如,book?address = 123_example_st_london) 。位置信息是输入内容的一部分,还是您以其他方式知道客户的位置信息?

Answers:


102

任何HTTP错误代码都是不合适的。从HTTP角度看,没有任何错误或问题,因此应该在200范围之内。您可以通过发回一个告诉他们的文档来礼貌地告知您的某些用户,他们将不会得到服务。而且一切顺利。

用户将无法使用您的应用程序。那是您的业务逻辑所做出的有意识的决定,而不是不幸的事。在HTTP级别,一切都是胡扯。

编辑

看来我们在这里看到的是旧学校与新学校的冲突。设计HTTP时,没有Web服务,没有SOAP,没有JSON,没有REST原理。作为TCP之上的协议,已经考虑(接近)应用程序级别,并且定义了许多高级状态代码。当网络开始用于更丰富,更高级的服务,并且需要一种通用的方式来传输“信封”时,设计人员劫持了HTTP,而不是定义一个更新,更干净的协议,只是因为HTTP无处不在。

因此,在现代的Web服务环境中,HTTP确实仅是愚蠢的传输层,其大多数代码可能被认为不适用或已过时。之所以选择一个,是因为它接近您的应用程序状态,并且恰好位于该列表中,这曾经意味着某些东西似乎无害,但我认为它将发送错误消息。您不希望HTTP在Web服务上下文中扮演该调节角色。


56
按照这种逻辑,任何应用程序错误均应返回200。所有请求都应为POST,甚至删除也是如此。这种方法将HTTP视为不透明的传输协议,例如TCP。这通常不是Web服务API的处理方式-它们试图利用HTTP语义和API的标准语言。为什么不为未授权返回401,而不是返回带有自定义非标准错误代码的200?
Avner Shahar-Kashtan '18年

31
按照这种逻辑,任何应用程序都不应返回400范围内的任何响应。这正是400种响应范围所适用的条件。另外,您的第一句话是否适用于所有以后的答案以及您之前发布的答案?
达伍德·伊本·卡里姆

31
我必须在这里同意这只是一个普通的200。用户问了一个问题,我们理解了这个问题,我们知道了正确的答案,并且我们已经为他提供了答案(碰巧是“否”)。HTTP领域一切顺利。
Lee Daniel Crocker

8
呵呵...从“这不是一个真正的错误”到“那么,您是说什么都没有错?”的
svidgen '18年

28
这个。“您尝试访问不存在的URL”与“我们公司不在您所在地区运营”非常不同。只有一个与HTTP有关。
CJ丹尼斯

88

5xx错误是服务器错误-服务器上出了点问题。特别是,503表示:

由于暂时过载或计划维护,服务器当前无法处理该请求

4xx错误是客户端错误-客户端正在发出服务器无法执行或不愿意执行的请求。特别是403表示

服务器理解了该请求,但拒绝对其进行授权。希望公开为什么禁止请求的服务器可以在响应有效负载(如果有)中描述该原因。[..]但是,出于与凭据无关的原因,可能会禁止请求。

我认为这503显然是不正确的,因为这不是暂时性的问题-您不支持该领域的请求。可以说出您最终希望支持该区域的理由,但是代码的目的是包含一个指示客户端何时可以重试的标头。“六个月之内”并没有遵循这个意图。

403 是更好的选择,因为您的服务仅禁止来自某些区域的请求。


403适用于禁止访问且客户端无法执行任何操作的情况。但是在这种情况下,客户可以(用笔记本电脑或手机上车),所以403是不合适的。
gnasher729

2
@ gnasher729 4xx错误是指客户端可能能够解决的问题,其中包括403。(链接的)规范明确指出客户端可以使用不同的凭据重试(假设出现凭据)。
jaxad0127 '18年

22
@ gnasher729 403并不意味着人类对此无能为力。这意味着浏览器无法执行任何操作。该人员始终可以重置密码,与管理员联系,或者在这种情况下,请移至其他城市。
slebetman '18

1
@ gnasher729客户端不是用户。
曼队长

10
5xx =糟糕,我们正在解决此问题,请耐心等待。4xx =很抱歉,根据政策,我们暂时无法满足您的要求。这就是为什么
。...–

46

都不是。

如果您的API设计合理,则URL包含城市名称,例如

http://example.com/API/Vienna/HailRide

要么

http://example.com/API/HailRide?city=Vienna

由于IP地理位置不可靠,因此您的用户可能正在使用VPN,您的用户可能想为其他人欢呼,等等。根据用户的位置建议城市是API客户端的责任。通常,客户端拥有更好的资源来确定用户的位置(例如,移动设备的位置服务)。

完成此操作后,正确的答案

http://example.com/API/SomeUnsupportedCity/HailRide

要么

http://example.com/API/HailRide?city=SomeUnsupportedCity

变得很明显:404未找到:在SomeUnsupportedCity上没有打车的资源。


6
这应该是公认的答案:API设计不仅要遵循旧的数字代码,而且有关vpn等的方案也很现实。
Edoardo '18年

10
我不同意这一点。在URL中包含城市名称可能会导致各种问题,因为这会迫使客户端根据位置确定城市名称,您可能不喜欢结果。例如,您在洛杉矶还是比佛利山庄?伦敦还是威斯敏斯特?如果客户认为它位于Richardson中,但是您希望API服务于整个达拉斯地区,会发生什么?对于客户来说,最好只提供接送地点。服务器可以确定它们是否在服务区域内,并做出相应的响应。
扎克·利普顿

11
@ZachLipton我敢肯定,城市名称只是一个例子,它取决于OP的实际业务规则,它们如何定义“城市”或“位置”。它也可以是一个坐标。
Bergi

1
@ZachLipton不,这里的意思是服务没有使用客户端IP来了解位置,这是错误的
Edoardo

3
@eddyce我同意出于多种原因使用客户端IP是一个坏主意。我说的是/ API / Vienna / HailRide也容易出现问题,因为它要求客户端将位置转换为城市名称,并且这与公司开展业务的区域不是一一对应的。
扎克·利普顿

26

这似乎是一个圆孔/方钉问题。为什么您唯一的响应需要是HTTP代码?HTTP错误代码可能无法涵盖所有​​用例。

您所有的API调用都应返回其他消息,即一些JSON错误消息。给他们一个403(因为,实际上,他们没有使用给定位置的API的许可)并按照您的建议返回其他信息。

如果您不这样做,那么下一次您将询问当用户要求SUV但只有Prius可用时返回什么HTTP错误代码。


5
为您的最后一句话+1。很好地总结一下。
LoztInSpace

1
好吧,这显然需要进行某种3xx重定向。;)
Brandon Mintern

最后一种情况可能需要某种4xx响应:用户发出了服务器无法满足的请求。如果选择是某种无效输入,则为400;如果位置本身不存在,则为404。虽然这可能是200,如果这是一个搜索条件并且没有匹配项。
jpmc26

11

一些有意义。

403 Forbidden,基于Eric Stein在回答中提到的原因。您可以使用请求提供的各种信息来确定客户端在哪里以及客户端是谁,并且基于该请求,服务器将无法或不愿响应。

但是,在某些情况下,我还会提出451由于法律原因不可用作为可能的退货状态。此状态确实希望您在标题中包含(链接到)相关法规的链接。它专门用于以下情况:客户端访问您的资源是不合法的,并且在不受支持的区域或区域中不存在客户端的更一般情况。

我会避免使用5xx系列状态-这些状态通常表示服务器端技术问题。这里似乎并非如此。


在这种情况下,可能的原因是没有必要告诉用户不在他们城市中的汽车。因此,对于451
max630

4
@ max630您不能从问题中假设这一点。403 Forbidden很可能是正确的选择。但是,如果对该服务有法律限制,则可以改用更具体的451。对于非常特殊的用例,451通常被视为403的更特定版本,因此提出它很有意义。
Thomas Owens

8
@ max630-451很可能在这里适用。许多司法管辖区要求提供此类服务的运营商必须先向区域当局注册。如果它们源自区域外,则实际上可能会从法律上禁止它们处理某些请求。
朱尔斯


3

人们经常忘记HTTP状态代码是可扩展的。

HTTP状态代码是可扩展的。不需要HTTP应用程序理解所有已注册状态代码的含义,尽管显然希望这样。但是,应用程序务必如第一位数字所示理解任何状态码的类别,并将任何无法识别的响应视为等同于该类的x00状态码,但不可识别的响应必须被缓存。例如,如果客户端接收到无法识别的状态码431,则它可以安全地假定其请求有问题,并将响应视为已接收到400状态码。在这种情况下,用户代理应向用户呈现随响应返回的实体,

https://tools.ietf.org/html/rfc2616#section-6.1.1

您始终可以只在400范围内创建自己的状态代码,以供API和客户端应用程序使用。


嗯...如果请求中包含Expect token;city="Albequerque"标头,则可能不需要。那么最合适的响应将是417,期望失败。 tools.ietf.org/html/rfc2616#section-10.4.18 当然,假设这是针对Web服务的。
Berin Loritsch '18

也许没有必要@BerinLoritsch,但不是试图迫使适合的情况到现有的代码,它可能是更好的只是踢和使用自定义的。
RubberDuck

0

起初我以为503是因为描述“服务不可用”似乎与该问题相符,但是查看定义 503确实是特定于服务器不可用的。然后再想想,您是在告诉客户端请求有问题,而不是服务器端问题。

403更接近,因为您告诉用户您已收到该消息并理解该消息,但是服务器不愿意满足该消息。这可能会造成混淆,因此可以添加文字说明来描述场景。根据RFC,404也是此代码的有效替代品。

除非有人为此梦想了一个新代码,否则403或404似乎是最接近的代码。


绝对不是5xx代码,因为这意味着稍后尝试完全相同的请求可能会成功。4xx代码肯定会告诉客户不要至少更改某些请求(在这种情况下,是“服务位置”字段)就不要重试。
Toby Speight

0

您应该将错误描述与您提供的代码相匹配:

  • 如果您说,Service not available in your area.那么您应该给a,404因为您声称该服务不可

  • 如果您说,You are not authorized for this service in your area.那么您应该给出一个,403因为您声称该呼叫者未被授权

我要去第二次。


6
404与可用性无关,而与存在有关。仅因为在某些情况下服务不可用,否则您不应提供404响应,除非您希望人们相信它根本不存在。对于这种情况,404响应将毫无意义。
朱尔斯

@jules根据403的规范(可能已过期):“如果服务器不希望将此信息提供给客户端,则可以使用状态代码404(未找到)。 ”强调我的。因此,如果403正常,则404也可以,但不一定出于给定的原因。
JimmyJames

@JimmyJames-是的,它在规范之内,但这是一个非常糟糕的主意,因为它使调试问题变得极为困难。不是您想要的API。
Jules

3
@Jules该服务在某些地区不存在。就像许多小商店只在我的城市中存在一样,因此询问他们在另一个城市中的地址,正确的回答是“不存在”。
安迪

ehmm谈论服务URL路径的“存在”是最少的-从哲学上讲,为了清楚起见,一旦发布路径,您必须提供答案,在这种情况下,使用403进行口头描述是情况。
Edoardo

0

有一个当前互联网草案(将在2018 12月31日到期),其建议修订HTTP 451不可出于法律原因状态。该草案建议451响应应包含一个geo-scope-block标头,该标头应“对应于[ISO.3166-1]中定义的以逗号分隔的alpha-2国家/地区代码列表”。但是,草案还指定不应使用代码451“由运营商根据运营商指定的策略(而不是对运营商提出法律要求)拒绝访问资源”。

因此,假设您对地理区块没有合法要求,则451不是正确的代码。那么正确的代码是什么?好吧,许多其他答案已经建议403 Forbidden,但它们似乎都是基于“观点”的,所以让我们看看其他人在做什么:

因此,没有一种通用的解决方案,您只需要选择一种您认为最适合自己情况的解决方案即可。但是无论您选择哪种方式,请务必在响应正文中说明实际问题

我想说,仅指定一个自定义HTTP状态代码就不会有错,例如RubberDuck已经回答。400范围内的自定义状态代码实际上甚至可以说是一个不错的选择,因为如果开发人员看到“ HTTP status 499”之类的信息,那肯定会引起开发人员的注意。“ 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.