接受HTTP 202(HTTP / 1.1)
您正在寻找HTTP 202 Accepted
状态。参见RFC 2616:
该请求已被接受进行处理,但是处理尚未完成。
HTTP 102处理(WebDAV)
RFC 2518建议使用HTTP 102 Processing
:
102(正在处理)状态码是一个临时响应,用于通知客户端服务器已经接受了完整的请求,但尚未完成。
但有一个警告:
请求完成后,服务器必须发送最终响应。
我不确定如何解释最后一句话。服务器是否应该避免在处理过程中发送任何内容,而仅在完成后做出响应?还是仅在处理终止时才强制结束响应?如果您想报告进度,这可能很有用。发送HTTP 102并逐字节(或逐行)刷新响应。
例如,对于一个漫长而线性的过程,您可以发送一百个点,每个字符后都冲洗一次。如果客户端(例如JavaScript应用程序)知道应该精确到100个字符,则可以将其与进度条匹配以显示给用户。
另一个示例涉及由几个非线性步骤组成的过程。在每个步骤之后,您都可以刷新一条日志消息,该消息最终将显示给用户,以便最终用户可以知道该过程的进展情况。
逐步冲洗的问题
请注意,尽管这项技术有其优点,但我不推荐使用。原因之一是它迫使连接保持打开状态,这可能会损害服务的可用性,并且无法很好地扩展。
更好的方法是使用进行响应,HTTP 202 Accepted
或者让用户稍后与您联系以确定处理是否结束(例如,通过反复调用给定URI,例如/process/result
将以HTTP 404 Not Found或HTTP 409 Conflict响应的方式进行处理,直到该过程为止)。完成并准备好结果),或者如果您能够通过消息队列服务(例如)或WebSockets 回叫客户端,则在处理完成时通知用户。
实际例子
想象一下一个转换视频的Web服务。入口点是:
POST /video/convert
它从HTTP请求中获取视频文件并对其进行处理。让我们想象一下魔术是CPU密集型的,因此它不能在请求传输期间实时完成。这意味着一旦文件传输完毕,服务器将以HTTP 202 Accepted
JSON内容响应,表示“是,我收到了您的视频,并且正在处理;它将在将来的某个地方准备就绪,并且可以通过ID 123获得。”
客户端可以订阅消息队列,以便在处理完成时得到通知。完成后,客户端可以通过以下方式下载处理后的视频:
GET /video/download/123
这导致一个HTTP 200
。
如果客户端在收到通知之前查询此URI,会发生什么情况?好吧,服务器将响应,HTTP 404
因为实际上视频还不存在。它可能当前正在准备中。可能从来没有要求过。它可能在过去的某个时间存在,并在以后删除。重要的是生成的视频不可用。
现在,如果客户不仅关心最终的视频,而且还关心进度(如果没有消息队列服务或任何类似的机制,这将显得尤为重要)怎么办?
在这种情况下,可以使用另一个端点:
GET /video/status/123
这将导致类似于以下的响应:
HTTP 200
{
"id": 123,
"status": "queued",
"priority": 2,
"progress-percent": 0,
"submitted-utc-time": "2016-04-19T13:59:22"
}
一遍又一遍地执行请求将显示进度,直到达到:
HTTP 200
{
"id": 123,
"status": "done",
"progress-percent": 100,
"submitted-utc-time": "2016-04-19T13:59:22"
}
区分这三种类型的请求至关重要:
POST /video/convert
将任务排队。它应该仅被调用一次:再次调用将使其他任务排队。
GET /video/download/123
涉及的结果操作的:在资源是视频。在这里,处理(即在请求之前独立于请求准备实际结果的幕后处理)无关紧要。可以调用一次或多次。
GET /video/status/123
关于处理本身。它没有排队。它不在乎最终的视频。该资源是处理本身。可以调用一次或多次。