2013-10-25 101 views
3

我发送POST请求使用下面的代码发送POST请求,复制文件并获得进展响应

$.ajax({ 
    url:filename, 
    type: 'post', 
    dataType: 'html', 
    data: {"data":someData}, 
    success: function(data) { 
     console.log(data); 
     alert(data); 
    }, 
    error:function(err){ 
     console.log(err); 
    } 
    }); 

这个函数的中拷贝文件拷贝文件,并给了我进步

function copyfiles($filename,$filesize){ 
    $remote = fopen('../filestorage/'.$filename, 'r'); 
    $local = fopen('../uploads/'.$filename, 'w'); 
    $read_bytes = 0; 
    while(!feof($remote)) { 
     $buffer = fread($remote, 2048); 
     fwrite($local, $buffer); 
     $read_bytes += 2048; 
     $progress = min(100, 100 * $read_bytes/$filesize); 
    echo json_encode(array("progress"=>$progress)); 
    } 
    fclose($remote); 
    fclose($local); 
} 

但我得到的是像下面的一个响应

 {"progress":16.956449743335}{"progress":33.91289948667} 
     {"progress":50.869349230005}{"progress":67.82579897334} 
     {"progress":84.782248716675}{"progress":100} 

我想逐个获取,然后显示进度s它被复制了多少。 请建议我该怎么做。

+0

是的。好的,请你告诉我我该怎么办。 – nyfer

回答

4

实现此目的的一种方法是有两个服务(或PHP页面等)。一个服务(s1)可能是您已经拥有的服务,它接受请求并开始复制。其他服务(s2)可能会响应正在复制的每个文件的状态。为了使这个工作,你需要采取以下考虑

  1. 服务S1应该具有ID或文件名即开始复制

  2. ;而拷贝进度应保持在地图,立即响应文件映射的关键进度值(记住用户可能需要复制多个文件)

  3. 客户应不断呼叫服务S2取得进步的价值观,传递作为参数的文件密钥

  4. 服务S2应该考虑的是地图和与请求的文件密钥的进展情况作出答复

服务和地图可以轻松地工作/存储与客户端的HTTP会话结合,以服务准确多个客户端。其他的存储方法可以选择,我认为http会话是这种情况下最直接和最恰当的。

编辑

这是一个PHP演示应用程序,其中一个服务S1为http会话写作和服务S2是从中读取。您的代码被留下注释,以显示您可以放置​​新代码的位置。

HTML/JS

<body> 
     <div> 
      <input type="radio" name="file" value="file1" />file1 
      <br/> 
      <input type="radio" name="file" value="file2" />file2 
      <br/> 
      <input type="radio" name="file" value="file3" />file3 
      <br/> 
      <input type="radio" name="file" value="file4" />file4 
      <br/><br/> 
      <input type="button" value="copy files" /> 
      <br/><br/> 
      <div class="output"></div> 
     </div> 
     <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> 
     <script>window.jQuery || document.write('<script src="jquery-1.10.1.min.js"><\/script>')</script> 
     <script> 
      var progressInterval; 
      $('input[type=button]').on('click',function(){ 
       var filename = $('input:checked').val(); 
       if(!filename)return; 
       $.ajax({ 
        url:'service-copy-file.php', 
        type: 'post', 
        data: {"filename":filename}, 
        dataType:'json', 
        success: function(data) { 
         console.log(data); 
         if(progressInterval) { 
          clearInterval(progressInterval); 
         } 
        }, 
        error:function(err){ 
         console.log(err); 
         if(progressInterval) { 
          clearInterval(progressInterval); 
         } 
        } 
       }); 

       progressInterval = setInterval(function(){ 
        $.ajax({ 
         url:'service-progress.php', 
         type: 'get', 
         data: {"filename":filename}, 
         dataType:'json', 
         success: function(data) { 
          console.log(data); 
          $('.output').text((parseInt(data.progress))+"%"); 
         }, 
         error:function(err){ 
          console.log(err); 
         } 
        }); 

       }, 1000); 

      }); 



     </script> 
    </body> 

服务S1

<?php 

copyfiles($_POST['filename'], null); 

function copyfiless($filename, $filesize) { 
    echo json_encode('copying ' . $filename); 
} 

function copyfiles($filename, $filesize) { 
    // $remote = fopen('../filestorage/'.$filename, 'r'); 
    // $local = fopen('../uploads/'.$filename, 'w'); 
    // $read_bytes = 0; 
    //emulate copying of a file for 10secs 
    $fileKey = $filename; 
    $progress = 0; 

    $_SESSION[$fileKey] = $progress; 
    // while(!feof($remote)) { 
    while ($progress < 100) { 
     session_start(); 
     // $buffer = fread($remote, 2048); 
     // fwrite($local, $buffer); 
     // $read_bytes += 2048; 
     // $progress = min(100, 100 * $read_bytes/$filesize); 
     // echo json_encode(array("progress"=>$progress)); 

     sleep(2); //emulate copying 
     $progress+=10; 
     $_SESSION[$fileKey] = $progress; 
     session_write_close(); 
    } 
    session_start(); 
    unset($_SESSION[$fileKey]); //completed copy 
    // fclose($remote); 
    // fclose($local); 
} 

?> 

服务S2

<?php 

session_start(); 

getProgress($_GET['filename']); 

function getProgress($filename) { 
    if (isset($_SESSION[$filename])) { 
     echo json_encode(array("progress" => $_SESSION[$filename])); 
    } else { 
     echo json_encode(array("progress" => -1)); 
     // echo json_encode('could not find file:'.$filename); 
    } 
} 

?> 

这会给真正的您的文件被复制的时间进度。但是,如果您想从服务器获取响应而无需从客户端进行轮询,则需要使用HTTP服务器推送,这需要更多努力来实现。

+0

+1逻辑在这里...... – JoDev

+0

@melc感谢您的回复。我试图用你的方式在客户端调用服务s1进行复制。此服务也调用服务s2中的方法来设置进度值。一旦我发送请求复制文件,我也发送请求到服务s2获取进度响应,但是得到的是空的结果。你可以告诉我,如果我错过了任何东西 – nyfer

+0

@nyfer s1应该将进度值存储在一个数组中,其中键值为文件名或唯一的值,并且可以为具有进度值或最后进度值的数组赋值。然后将数组存储在用户的会话中,http://www.w3schools.com/php/php_sessions.asp。无需从s1请求s2。当客户端使用从s1返回的文件名键调用s2时,s2应检查会话并返回进度。如果您确实需要,我会尽量在一天内发布一些代码。 – melc

1

我这样做的唯一时间是4年前。不知道这是否会帮助你,但是这是我的系统:

  1. 当执行长处理(不仅是文件传输)的PHP用来做什么的有存储过程到一个文件中(或MySQL的数据库...)不要忘记关闭文件(如果你选择一个文件)的阅读权限!

  2. 在这个

    ,回调(在ajax了,但对我来说是一个自动更新)调用一个PHP函数,返回当前过程值读取文件(或DB)

合我会帮你的!