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

时间:2010-05-28 14:39:01

标签: http redirect asynchronous twisted post-redirect-get

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

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

所以问题是:是否有可能在纯HTTP中做到这一点(在客户端没有JavaScript),如果是这样,怎么做?

3 个答案:

答案 0 :(得分:15)

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

  1. 立即(突然)关闭连接,为客户端会话存储服务器端标志
  2. 使用该标志检测尝试重新发送相同的表单数据,规范建议客户端自动执行此操作
  3. 使用重定向发送错误状态(如302暂时移动)
  4. 应该有效,因为如下所述,客户端应在意外切断后至少重试一次连接。在重试尝试时,它应该只发送标题,然后等待并观察错误响应并在中断发送主体时中止。

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

      

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

         

    如果HTTP / 1.1客户端发送请求   其中包括请求正文   其中不包括Expect   请求标头字段   “100-继续”的期望,如果   客户端没有直接连接到   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.
    
         

    如果在任何时候出现错误状态   收到了,客户

      - SHOULD NOT continue and
    
      - SHOULD close the connection if it has not completed sending the
        request message.
    

    陷阱:

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

答案 1 :(得分:3)

看一下django ticket #10850 - "Impossible to stop a large file upload mid-stream"。没有解决问题,但至少它应该有助于你理解它。

答案 2 :(得分:-1)

  1. 如果您使用apache,则使用PCEL uploadprogress扩展
  2. 创建一个文件以通过Ajax轮询元数据,并根据您的条件返回true或false,您也可以获取temp_name文件并检查1kb元数据。
  3. ajax调用需要绑定一个函数,该函数使用HTML元刷新标头重定向或保持直到上传完成。

  4. 查看uploadprogress示例。