Web 服务器能否在客户端发送完整请求之前开始响应?
Posted
技术标签:
【中文标题】Web 服务器能否在客户端发送完整请求之前开始响应?【英文标题】:Can a web server begin responding before the client has sent the full request? 【发布时间】:2017-12-21 12:11:19 【问题描述】:我正在为一个学术研究小组编写一个 Web 应用程序。研究人员需要能够上传 CSV 格式的大型数据集(100MB - 1GB)。我已经编写了服务器来处理传入的数据。这意味着如果 CSV 的第一行有错误,我们可以立即返回错误。
但是,发生这种情况时,浏览器会报告“连接已重置”或类似信息。显然,我的网络服务器以一种没有意义的方式响应。
如果我在将错误返回给浏览器之前显式关闭 HTTP 请求流(顺便说一下,这是 JVM 上的 Kotlin),那么问题就会消失。然而,事实证明,请求流的关闭实现首先将整个流读取到其末尾。因此,此时用户仍需等待 30 分钟以上才能发现其 CSV 的第一行存在错误。
我正在尝试做的事情可能吗? HTTP 协议是否允许 Web 服务器在任何情况下在完整的请求正文发送之前开始响应?如果没有,您能否建议一种解决方法,让我提供一种用户体验,让用户不必等待整个文件上传后才知道是否有任何问题?
【问题讨论】:
分块上传(有很多例子),然后检查每个块是否有问题,出错。 您可以使用异步请求并循环通过 CSV 一次发送一行,具体取决于您用于发送文件的应用程序。如果是浏览器,您可能可以使用 html5 文件 API 感谢您的建议。我觉得你在回答我关于解决方法的问题。这是否意味着您认为 HTTP 协议不允许我这样做,或者您不确定? 【参考方案1】:答案是肯定的,根据 http 规范,服务器应该能够提前发送响应,客户端应该停止发送请求正文。然而,大多数浏览器并没有正确实现这一点。
理论上,您的 http 服务器需要返回一个带有响应正文的 4xx 错误代码,然后重置连接以防止在后台继续上传。有关该问题的更详细说明,请参阅下面的答案。有几个浏览器版本支持此功能,因此如果您在实验室条件下执行此操作,您可以控制正在使用的客户端,下面的链接会有所帮助。
https://***.com/a/14483857/2274303
https://***.com/a/18370751/2274303
[编辑]
要回答您关于使用解决方法的问题,使用 javascript 对上传进行分块是缓解 Internet 连接问题的好方法,但如果您想实时解析它,它并不像任意将文件分解成碎片那么简单。您需要确保您没有在一行中间拆分文件,否则即使数据有效,它也会失败。这带来了在 javascript 中解析 1GB 文件的问题,这在 imo 中不是一个好主意。
如果您想使用 javascript,请继续通过 ajax 请求一次上传整个文件,这样您就可以在主 dom 之外获得响应并强制重定向或取消上传。根据您使用的 js 库,有不同的方法。
这些都不能解决相反的情况。如果文件在出现错误之前上传了 95% 怎么办?研究人员将需要再次上传整个内容或编辑文件以仅包含错误中的行。这意味着您的应用程序需要支持部分上传并知道从中断的地方继续。所有这些事情都是可能的,但您可能不会找到一个简单的解决方法来使其正常工作。
如果不了解数据集以及您正在执行哪种验证,就很难提出完整的解决方案。如果解析每一行不依赖于前面的行是否有效,您总是可以上传整个文件,然后在最后显示有错误的行,并要求他们上传第二个文件,只进行更正。
【讨论】:
【参考方案2】:HTTP Web 服务器的正常流程如下:
Server listens for request
Client creates request
Client sends request to server
Server processes request
Server creates response
Server sends response to client
Client processes response
客户端启动连接进行通信,服务器能够对该连接做出响应,但是如果您关闭连接,服务器将需要在另一个连接上发送响应。浏览器可能不允许服务器启动客户端未请求的新连接。
您可以通过读取第一行并快速创建错误来做出响应,但客户端在完成发送请求之前不会读取响应。
通过分块发送文件或异步发送文件行,您将能够更及时地提供反馈。您将发送许多较小的请求,并且能够在两者之间做出响应。
问题是关于 HTTP 协议的。我觉得如果您编写自定义应用程序和 Web 应用程序,协议将允许这样做,但是如果您使用浏览器,那么您必须使用 HTTP,因为公司已经实现了它。在自定义应用程序中,您可以检查中断,但大多数浏览器可能会在侦听响应之前触发完整的请求,这也是 AJAX 在 20 年前起飞的原因。
【讨论】:
以上是关于Web 服务器能否在客户端发送完整请求之前开始响应?的主要内容,如果未能解决你的问题,请参考以下文章