我们可以创建自定义 HTTP 状态代码吗?

Posted

技术标签:

【中文标题】我们可以创建自定义 HTTP 状态代码吗?【英文标题】:Can we create custom HTTP Status codes? 【发布时间】:2011-12-21 05:55:10 【问题描述】:

我有一个 REST 和 WCF 服务,并希望根据操作发送自定义状态代码。

例如,当某些验证失败时,我想发送 HTTP 444,而当授权失败时,我想发送 HTTP 455

问题是我们如何验证 SOAP 和 REST Web 服务。

在客户端上,错误代码是如何起作用的,因为当您从 WCF 服务(使用 SOAP)发送 HTTP 400/500 时,会在客户端上引发显示状态代码的异常?

现在,如果我发送一个新的自定义状态码,客户端如何处理?

【问题讨论】:

这是您向世界公开的服务,还是您也控制所有客户端? 【参考方案1】:

这是所有可用/不可用HTTP 代码的完整列表。

https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml

例如,可以在4XX family 上使用以下带箭头的(因为它们未分配)。

我希望这对某人有所帮助。

谢谢

【讨论】:

【参考方案2】:

我建议您不要创建自己的 HTTP 状态代码,而 applicable codes already exist 用于您想要在示例中执行的操作。

无法处理的故障:状态 422 Authorization failure:状态 403

来自https://www.rfc-editor.org/rfc/rfc4918#section-11.2:

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

可以说“无法处理”可能是由于验证错误。

【讨论】:

授权失败是401,不是403。403是禁止的,授权不能解决问题。 401 是关于失败的身份验证(尽管名称)。 401 是“请再次登录”【参考方案3】:

是的,只要您尊重类 - 即 2xx 表示成功,4xx 表示客户端错误等。因此,您可以为自己的应用程序的错误条件返回自定义的 4XX 错误代码(最好是未分配的错误代码)。

引用 [RFC 2616][1]:

"HTTP 状态码是可扩展的。不需要 HTTP 应用程序 了解所有注册状态代码的含义,尽管这样 理解显然是可取的。但是,应用程序必须 了解任何状态代码的类别,如第一个所示 数字,并将任何无法识别的响应视为等效于 该类的 x00 状态代码,除了 不得缓存无法识别的响应。例如,如果一个 客户端收到无法识别的状态码431,可以 安全地假设它的请求有问题,并且 将响应视为收到 400 状态代码。”

类'

1xx:信息性 - 已收到请求,继续处理

2xx: Success - 成功接收到动作, 理解并接受

3xx:重定向 - 必须采取进一步措施才能将 完成请求

4xx:客户端错误 - 请求包含错误语法或不能 应验

5xx: 服务器错误 - 服务器显然未能完成 有效请求 [1]:

https://www.rfc-editor.org/rfc/rfc2616#section-6.1.1

【讨论】:

请勿使用未注册的状态码,测试除外。 ChrisNY:好吧,如果您在使用 HTTP 时依赖未注册的状态代码,那么如果其他人将相同的代码用于不同的目的,则可能会损坏。如果您需要更详细的错误信息,您仍然可以将其嵌入到有效负载中(例如参见tools.ietf.org/html/draft-nottingham-http-problem-06) @ChrisNY:大多数 Web 应用程序都设计为与单个客户端(您的 javascript/ajax 代码)和单个服务器(您的服务器)一起使用,因此使用自定义状态代码是完全可以的。在这些情况下,“其他人”甚至不可能通过使用相同的状态码来导致“损坏”。 这句话并不是说您可以编写自己的代码,而是说您的应用不需要知道每个注册代码是什么,只要它尊重代码类并抛出错误一个 4xx 等。除此之外,我能看到的唯一问题是,将来,这些代码之一会被正式分配,并且浏览器/javascript 功能可能会改变。例如494 DDNS 攻击停止所有通信,浏览器可能会看到并阻止 js 向该 IP 发起更多通信。极不可能,但你不能 100%,Twitter 似乎认为可以做 420 增强你的平静 规范是说你可以自己编代码,以代码471为例。它说假设任何无法识别的 4xx 错误等同于 400。【参考方案4】:

某些应用程序会在 600-799 范围内添加其自定义响应代码。检查例如响应代码列表from KeyNote here

Keynote 定义的错误代码 (600-799)

600: CONNECTION ERROR - This indicates a general connection error
601: INCOMPLETE ERROR - This indicates sever sends an incomplete page/object (as indicated by Content-Length header)
602: UNEXPECTED CLOSE ERROR - This indicates socket connection has been closed unexpectedly
603: REFUSED ERROR - This indicates a request to connect to the server is refused
604: TIMEOUT ERROR - This indicates there is no activity in socket connection in 3 minutes
605: REDIRECT ERROR - This indicates an error in redirect HTTP header
606: SSL ERROR - This indicates a general error in SSL
607: HEADER ERROR - This indicates a malformed HTTP header
608: EMPTY RESPONSE ERROR - This indicates server doesn't send any response after a request is sent
609: UNKNOWN HOST ERROR - This indicates socket receives an unknown host error from DNS
610: NO ROUTE TO HOST ERROR - This indicates a no route to host error was received while attempting to open a socket
611: SOCKET ERROR - This indicates a general socket error
612: FRAME LOOP ERROR - This indicates a page has a frame loop (frame A includes Frame B that includes Frame A)
613: REDIRECT LOOP ERROR - This indicates a page has a redirect loop (page A redirects to page B that redirects to page A)
614: CONNECTION RESET ERROR - This indicates socket receive a reset signal from the server
615: SOCKET PROTOCOL ERROR - This indicates an error in socket protocol
616: SOCKET BIND ERROR - This indicates an error in binding the socket
617: CONNECTION ERROR - This indicates a general socket connection error
618: CHUNK ERROR - This indicates an error in chunked encoding
619: SSL TIMEOUT - This indicates a timeout during SSL handshake (2 minutes)
620: SSL END OF INPUT - This indicates an end-of-file is received during SSL handshake
621: SSL HANDSHAKE ERROR - This indicates a general error during SSL handshake
622: SSL CERTIFICATE ERROR - This indicates an error in SSL certificate verification
623: SSL AUTHENTICATION ERROR - This indicates an authentication error during SSL handshake
624: SSL BAD MAC ERROR - This indicates a bad MAC during SSL handshake
625: SSL CIPHER ERROR - This indicates a cipher error during SSL handshake
701: ERROR TEXT FOUND - This code is returned if any error text (such as, "Service Unavailable") are found in the main page (frame HTML contents included). Note that the error text must be defined in advance of the test. Error text means if the text is found, this session should be considered a failure.
702: REQUIRED TEXT NOT FOUND - This code is returned If not all required texts are found in the main page. Note that required text must be defined in advance of the test. Required text means if the text is not found, this session should be considered a failure.
703: HTML BODY EMPTY - This code is returned if the HTML body of the page is empty (only if error text or required text has been defined).

这是否是好的做法我不敢说,但至少是一个有趣的参考。

【讨论】:

这些值是非法的,因为 HTTP 规范不允许 100...599 之外的任何值。 @JulianReschke 我什至提到我“不敢说这是否是好的做法”。我只是添加了对其他应用程序的引用。否决我的答案,因为 Keynote 使用非法状态代码似乎不合理。我只是在讨论。 @Wilt 如果您想参与讨论,请在 cmets 中进行。【参考方案5】:

是的,您可以添加自定义错误代码。如果可能,请使用已经存在的代码,如果您要声明新代码,请小心避免冲突。

您应该知道,有些代理会过滤未知代码。我遇到了用户问题,即代理将 5XX 映射到 500,将 4XX 映射到 404。这使得我的 ajax 调用检查状态代码失败。

【讨论】:

是的,代理很糟糕。我不知道代理实现名称,但它自己解释了我们的自定义状态码,并没有将响应发送给客户端。【参考方案6】:

不行,只能使用 rfc 文档需求代码,详见RFC1945

【讨论】:

您可以使用iana.org/assignments/http-status-codes中定义的任何状态码。 @Julian,这是否意味着 Rajesh 可以将“427-499 Unassigned”用于他的目的? OK then :-) 您可以使用该列表中的任何 assigned 状态代码。或者你为一个新的状态码写一个规范并注册它。 从技术上讲,您可以随意使用您喜欢的任何东西。只是不要指望它与其他人一起玩得很好。正如 OP 中所问的那样——如果 Rajesh 控制所有客户,他可以让他们理解“1337 - 你所有的基地都属于我们”,他们很高兴。 ;) 您链接到 HTTP/1.0 状态码,自 90 年代初期以来就没有使用过。

以上是关于我们可以创建自定义 HTTP 状态代码吗?的主要内容,如果未能解决你的问题,请参考以下文章

通过curl命令获取http的状态吗

swift上的Alamofire返回状态代码问题

为 Jackson 自定义反序列化程序抛出带有 HTTP 状态代码的自定义异常

所有视图都应该是无状态组件吗?

Spring Boot 异常自定义处理 - 意外的 HTTP 状态

Spring MVC 返回自定义 HTTP 状态码(无错误)