ChatGPT解决这个技术问题 Extra ChatGPT

部分成功请求的 HTTP 状态代码

我有一个向用户发送消息的应用程序。在 post 请求中传输一个 XML 字符串,该字符串由应接收该特定消息的所有用户组成。如果列表中的任何用户不存在,我会将丢失用户的列表返回给客户进行进一步评估。

现在我问自己,应用程序的正确状态代码是什么,表示请求已被接受,但有些事情无法完成。

如果不允许在列表中包含丢失的用户,则可以避免该问题。然后发送尝试只会得到一个 4xx 错误。但是以这种方式形成 API 是没有意义的。另一方面,我可以认为错误条件纯粹是特定于应用程序的。但是发送 200 感觉不对。最好给客户一个提示,什么时候深入查看错误响应。例如,避免一遍又一遍地向该用户发送消息


K
Kylar

我处理过一个非常相似的问题。在这种情况下,我返回了一个

207 多状态

现在,这不是严格的 HTTP,它是 WebDAV 扩展的一部分,所以如果您也无法控制客户端,那么这对您不利。如果你这样做,你可以这样做:

   <?xml version="1.0" encoding="utf-8" ?>
   <D:multistatus xmlns:D='DAV:'>
     <D:response>
       <D:user>user-123</D:user>
       <D:status>success</D:status>
     </D:response>
     <D:response>
       <D:user>user-789</D:user>
       <D:status>failure</D:status>
     </D:response>
   </D:multistatus>

但同样,这是一个 HTTP 扩展,您还需要控制客户端。


我考虑过使用它,但我对它不太满意。谢谢!
它的好处是您可以根据需要返回尽可能多或少的相关数据 - 这对于混合数据集特别有用,即:有些失败而有些通过。
我明白。我只是想避免额外的状态处理(恕我直言,这不是很好)。我的大部分代码都适用于 HTTP 代码。而且我认为没有我描述的用例会很好。
您始终可以发回一个正文 - 发送一个带有 JSON 响应的 200 或您想要的任何内容,以确定哪些是成功的。
是的,我知道。但是如果你返回一个身体,你需要解析它。在那一刻,您引入了第二层应用程序逻辑处理。这会增加复杂性,您需要有充分的理由这样做。
A
Arne

我遇到了同样的问题,我最终使用了两种不同的解决方案:

HTTP 返回码 202:已接受,表示请求正常,但不能保证一切都按预期进行。

在响应中返回正常的 200,但在响应正文中包含未成功的列表。

第二个通常效果最好,但如果你很懒或使用队列进行处理,第一个很好。


202不是更多地指的是排队之类的东西吗?
是的,@Sinaesthetic。从最新的 HTTP 1.1 规范中,“(...) 请求已被接受处理,但处理尚未完成”。因此,对于部分成功,202 是不合适的。
IMO 200 明确允许部分成功,因为负载的预期含义被指定为 POST、PUT 和 DELETE 的状态。 tools.ietf.org/html/rfc7231#section-6.3.1 状态 202 是异步调用的成功启动,其结果未知。类似于获得承诺/未来。响应应该说明如何获得实际结果或至少监控状态。
C
Cem Kalyoncu

我需要同样的问题,在阅读了一些文档之后,这个问题的最佳解决方案似乎是用非标准的 2xx 响应来响应。一般客户会将此视为成功,但特定客户可以理解发生了什么。您也可以使用表单 X-failed: thispart code 中的自定义标题来支持这一点。您可能应该将操作的问题作为文本包含在内,以便通用客户端能够显示发生的事情的性质。这是我在上传文件但目前无法完成处理的地方所做的事情:

HTTP/1.1 210 Partial success
X-failed: processing
X-reason: server busy

File has been uploaded, however, the task associated with the 
file has not started as the server is busy. Re-request processing
at a later time.

Y
Yusuf

使用 206 部分内容怎么样。我知道 206 更多的是关于范围,但是如果它可以指示部分成功的请求怎么办?


MDN 声明如下:“HTTP 206 Partial Content 成功状态响应代码表示请求已成功,并且正文包含请求的数据范围,如请求的 Range 标头中所述。”据我了解, 206 Partial Content 严格用于具有内容范围的请求。
W3C RFC 文档还指定 206 用于部分完成的 GET 请求,而不是 POST。 The server has fulfilled the partial GET request for the resource. The request MUST have included a Range header field (section 14.35) indicating the desired range, and MAY have included an If-Range header field (section 14.27) to make the request conditional. w3.org/Protocols/rfc2616/rfc2616-sec10.html
A
AVee

超文本传输协议处理事物的传输方面。它没有处理应用程序级错误的错误代码。

返回 200 是正确的做法。就 HTTP 而言,请求被正确接收,处理得当,并且您正在发回响应。因此,在 HTTP 级别上一切正常。与在 http 之上运行的应用程序相关的任何错误或警告都应包含在响应中。这样做还可以防止您在使用代理服务器时遇到的一些令人讨厌的问题,这些问题可能无法按您期望的方式处理某些响应。


HTTP 是应用层协议。您不能简单地将其放在传输和应用程序级别。如果您考虑 OSI,那么 HTTP 位于第 5-7 层。 HTTP 有点不同。大多数标头和返回代码确实是特定于应用程序的。这些代码仅取决于 HTTP 协议实体中给出的信息,而不是自定义应用程序格式的东西。关于 200,我会说,如果将其应用于不是 POST 的动词,则您的定义是完全错误的。但是 POST 稍微改变了游戏规则,在这种情况下,您的假设“处理得当”也不确定
严格来说,OSI 认为 HTTP 是一种应用程序级协议,当与“普通”网络服务器通信时,这是正确的。但是在您的情况下,您正在 HTTP 之上运行自己的协议,就像现在许多应用程序一样。在那种类型的使用中,HTTP 只是提供传输。 (您的应用程序正在向用户发送消息,而不是传输超文本......)
只是要清楚。 REST 方式的 HTTP 以资源为中心。在这种情况下,200 表示身份(您指定的资源),而不是指向身份方向的 3xx。使用 POST 将资源 URI 转换为处理 URI,并且需要处理错误代码。上下文发生了一点变化,事物的定义变得有点模糊或至少难以理解
上下文转换也意味着没有合适的错误代码,因为该协议从未在设计时考虑到该上下文 ;-) 我还认为您应该小心使用错误代码,因为代理服务器倾向于使用它们来替换您的响应自定义错误页面,这可以是一个真正的 PITA。
无论如何,谢谢你回答我的问题。我刚刚发现 stackoverflow 是一个糟糕的聊天客户端 :)