在POST上载之前重定向已完成

var*_*tec 20 redirect asynchronous http twisted post-redirect-get

我有表格上传文件.要上传的文件实际上是图片和视频,因此它们可能非常大.我有基于标题的逻辑,首先1KB可以确定其余的是否会被处理或立即被拒绝.在后一种情况下,我想将客户端重定向到错误页面,而不必等待上传完成.

情况是,只是在POST完成之前发送响应似乎不起作用.重定向被忽略,如果我关闭连接,浏览器会抱怨"Connection reset by peer"错误.

所以问题是:甚至可以在纯HTTP中实现这一点(在客户端没有JavaScript),如果是这样,怎么样?

Spl*_*iFF 15

HTTP/1.1协议允许这样做,只是以一种非常奇怪和混乱的方式.您需要应用以下3个步骤:

  1. 立即(突然)关闭连接,为客户端会话存储服务器端标志
  2. 使用该标志来检测重新发送相同表单数据的尝试,规范建议客户端自动执行此操作
  3. 使用重定向发送错误状态(如302临时移动)

应该工作,因为如下所述,客户端应该在意外切断后至少重试一次连接.在重试尝试时,它应该只发送标题,然后等待并观察错误响应并中止发送正文(如果有的话).

http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html

8.2.4服务器过早关闭连接时的客户端行为

如果HTTP/1.1客户端发送包含请求主体的请求,但不包含具有"100-continue"期望的Expect请求标头字段,并且客户端未直接连接到HTTP/1.1源服务器,如果客户端在从服务器接收任何状态之前看到连接关闭,则客户端应该重试该请求.如果客户端重试此请求,它可以使用以下"二进制指数退避"算法来确保获得可靠的响应:

  1. Initiate a new connection to the server

  2. Transmit the request-headers

  3. Initialize a variable R to the estimated round-trip time to the
     server (e.g., based on the time it took to establish the
     connection), or to a constant value of 5 seconds if the round-
     trip time is not available.

  4. Compute T = R * (2**N), where N is the number of previous
     retries of this request.

  5. Wait either for an error response from the server, or for T
     seconds (whichever comes first)

  6. If no error response is received, after T seconds transmit the
     body of the request.

  7. If client sees that the connection is closed prematurely,
     repeat from step 1 until the request is accepted, an error
     response is received, or the user becomes impatient and
     terminates the retry process.
Run Code Online (Sandbox Code Playgroud)

如果在任何时候收到错误状态,则客户端

  - SHOULD NOT continue and

  - SHOULD close the connection if it has not completed sending the
    request message.
Run Code Online (Sandbox Code Playgroud)

陷阱:

  1. 这就是规范说browswers 应该做的.谁知道在这种情况下哪些浏览器实际上做了什么?不是我.你需要运行一些测试.
  2. 规范特别提到此行为仅适用于" 如果客户端未直接连接到HTTP/1.1源服务器 ".这似乎是一个非常奇怪的要求,在实践中意味着您可能需要假装您的服务器响应标头假装您是代理或HTTP/1.0服务器.
  3. 在请求完成之前,某些中间协议(如fast-cgi)可能无法激活您的脚本.在这种情况下,您实际上需要一个真正的低级套接字服务器.
  4. 这整个过程很混乱,也很复杂,甚至可能都不起作用.在我看来,你最好使用AJAX.尽管如此,你确实问过它是否可以在没有JS的情况下完成.