取消请求的正确 HTTP 状态代码是啥

Posted

技术标签:

【中文标题】取消请求的正确 HTTP 状态代码是啥【英文标题】:What is the Correct HTTP Status Code for a Cancelled Request取消请求的正确 HTTP 状态代码是什么 【发布时间】:2018-02-24 08:34:31 【问题描述】:

当客户端在发出 HTTP 请求时取消 TCP 连接时,我想停止在服务器上执行任何工作并返回空响应。这样的响应应该返回什么 HTTP 状态码?

【问题讨论】:

当一个请求被取消时,客户端会读取服务器响应吗? “取消”到底是什么意思?你试过什么?为什么每天有十个“我的情况很独特,告诉我应该使用大约 20 个状态代码中的哪一个” 问题?这真的重要吗? 这仍然很重要,因为缓存、浏览器开发工具和其他中介仍然会读取响应。到目前为止,我只是在使用 400 Bad Request 但感觉不对。这不是一个独特的情况,我很惊讶没有答案。状态代码都是关于语言的,这就是为什么很难知道使用哪个。您在 API/站点中使用的语言很重要,因为它传达了意图。如果我的浏览器取消了一个请求,并且我在 F12 开发者工具中看到 400 Bad Request,这表明该请求无效,这是不正确的意图。 HTTP 中无法让客户端取消请求。因此,没有定义任何代码供服务器返回也就不足为奇了。 我认为考虑取消请求的原因非常重要,而不是为任何被取消的请求寻找一个特定的代码。 如果服务器仍然可以发送,那么它可以发送它想要的任何响应,包括请求的完整休息。客户端取消(关闭其发送部分)仅意味着服务器将不再从客户端接收任何数据。客户端可能会继续从服务器接收剩余的结果。另一方面,如果客户端关闭了套接字的两半,那么服务器在接下来对该套接字执行任何操作时都会收到错误消息,并且无需再向客户端发送任何内容即可恢复。 【参考方案1】:

只有几个可能的选择(当然,除了 500 个):

    202 接受

    你还没有完成处理,你永远不会。

    仅当在您的应用程序域中,原始请求者“预期”并非所有请求都将得到满足时,这才是合适的。

    409 冲突

    …在提出和取消请求之间。

    这只是微不足道的理由:您的情况不涉及一位客户根据过期信息提出请求,因为取消尚未发生。

    503 服务不可用

    该服务实际上对这一请求不可用(因为它已被取消!)。

"report an error as an error" 的一般参数偏爱 409 或 503。所以 503 默认情况下。

【讨论】:

【参考方案2】:

HTTP (1.0/1.1) 无法取消请求。如果客户端不再需要响应,它所能做的就是关闭连接并希望服务器包含优化以停止处理无法再传递的响应。由于连接现在已关闭,实际上无法将响应或状态代码传递给客户端,因此您“返回”的任何代码都只是为了您自己的满意。我个人会选择 4xx 范围内的东西1,因为“故障”(您无法再提供响应的原因)是由于客户造成的。

HTTP 2.0 确实允许端点发出END_STREAMRST_STREAM 来表明他们不再对一个流感兴趣,而不会断开整个连接。但是,它们只是忽略在该流上发送的任何进一步的HEADERSDATA,因此即使理论上您可以传递状态代码,客户端仍然会完全忽略它。


1可能是 400 本身,因为我无法确定似乎完全合适的更具体的错误。

【讨论】:

似乎相关en.wikipedia.org/wiki/HTTP_451:服务器操作员已收到拒绝访问某个资源或包含所请求资源的一组资源的合法要求。 @TheChetan:这是为了审查,而不是异步取消。 @TheChetan - 再一次,这里的上下文似乎是来自客户端而不是服务器的“取消” - 这当然不是 HTTP 概念。 即使在过去 (HTTP 1.x) 中,您也可以关闭套接字的发送 half,而让接收 half 保持打开状态。服务器关闭,但它仍然可以发送响应,如果它愿意。【参考方案3】:

为了保持一致,我现在建议400 Bad Request,如果您的后端应用程序能够识别客户端何时断开连接,或者您拒绝或关闭连接,您可能会返回 nginx 的非标准代码 499 或 444。

499 客户端关闭请求 当客户端在服务器发送响应之前关闭请求时使用。

444 无响应 用于表示服务器没有向客户端返回任何信息并关闭连接。

【讨论】:

204 No ContentThe server successfully processed the request and is not returning any content. 似乎也非常适合 OPs 主题。 没有内容不适合超时。 204 表示服务器端可能发生了一些变化,例如实体已更新【参考方案4】:

真的没什么可做的。引用RFC 7230, section 6.5:

客户端、服务器或代理可以随时关闭传输连接。

这发生在 TCP 级别,而不是 HTTP 级别。只需停止处理连接。状态码在这里几乎没有意义,因为不完整/中断请求的意图只是推测。此外,将无法将其传输给客户端。

【讨论】:

虽然客户端不会收到此状态代码,但您的日志记录/指标收集应该并且在很多情况下知道响应没有作为客户端完成在弄清楚如何使服务/服务器更好时,取消很重要。

以上是关于取消请求的正确 HTTP 状态代码是啥的主要内容,如果未能解决你的问题,请参考以下文章

Preflight(options) 请求的正确成功状态代码是啥? [复制]

未找到搜索结果的正确 HTTP 状态代码是啥?

如果资源不可用于请求的操作,HTTP 状态代码应该是啥?

在 ajax 错误(HTTP 状态代码 0)中区分失败(无网络)和取消请求

错误代码:400指的是啥错误?

对于一般不成功的请求(不是错误),适当的 HTTP 状态代码响应是啥?