Javascript多文件上传,一次一个

时间:2009-12-02 15:02:02

标签: javascript jquery iframe asynchronous file-upload

我们有一个包含五个<input type="file"/>元素的表单,这些元素已投入生产并且运行良好。我们得到请求超时,MaxRequestLength偶尔会超出错误。为了防止这些错误,我计划编写一些Javascript来一次一个地上传文件,而不是一次上传所有文件。这就是我计划这样做的方式......

  1. 在document.ready上,将隐藏的iframe注入页面
  2. 更改<form>以定位iframe
  3. 禁用表单上的所有元素(这会阻止它们被POST)
  4. 一次启用一个文件上传并提交表单
  5. 等待来自服务器的响应
  6. 将服务器响应打印到iframe时,启动下一次上传
  7. 完成所有上传后,刷新页面,这将调用一些填充网格的服务器端逻辑。
  8. 我的问题是5号。通常情况下,我认为我可以解决这个问题,但我只是有一天我的大脑正在罢工。这是我到目前为止的代码......

    $(function() {
      $("<iframe/>").attr("src", "test.htm").attr("name", "postMe").hide().appendTo("body");
      $("form").attr("target", "postMe").submit(function(e) {
        e.preventDefault();
        $("#btnSubmit").attr("disabled", "disabled").val("Please Wait, Files are Uploading");
    
        for(var i = 1; i < 6; i++) {
          $("input[type=file]").attr("disabled", "disabled");
          $("#FileUpload" + i).removeAttr("disabled");
          $("form")[0].submit();
          // HELP!!!
          // How do I wait for server before next iteration?
        }
    
        location.reload(true);
      });
    });
    

    我在这里需要什么样的构造才能在开始下一次上传之前“等待”服务器响应?

5 个答案:

答案 0 :(得分:2)

我最近使用Uploadify取得了很多成功 - 它非常可配置,免费,并允许多次上传。它还提供了回调函数选项,允许您以任何方式真正配置它。

http://www.uploadify.com/

答案 1 :(得分:1)

我认为你应该监听iframe加载事件并在处理程序中执行输入切换。我今天完成了我自己的上传器,这个解决方案对我有用。

答案 2 :(得分:1)

仅供参考:jquery.forms插件是关于制作ajax形式的子目录。我使用这个插件在一个单独的iframe中提交一个表单(例如文件上传),该插件自动处理,并在完成时给你一个很好的回调。

这样就可以完成大部分工作。

http://jquery.malsup.com/form/

答案 3 :(得分:1)

可以借助jQuery的queue方法和load事件来完成。

<!DOCTYPE HTML>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script>
//here's an upload script
(function($){
    //make 'em accessible within the scope
    var $iframe, $form;

    $(document).ready(function(){
        //create 'em only once, but use 'em many times
        $iframe = $('<iframe name="iframe" id="iframe" style="display:none"></iframe>').appendTo('body');       
        $form = $('<form method="post" enctype="multipart/form-data" target="iframe" style="display:none"></form>').appendTo('body');   
    });

    var iframeUpload = $({});

    $.iframeUpload = function(s){   
        iframeUpload.queue(function(next){
            //as we only wanna this new event
            $iframe.load(function(){
                //we must unbind the old one
                $iframe.unbind('load');

                //success or error, the question is up to you
                s.success();

                //but remember to remove or replace the old stuff
                $form.find('input').remove();

                next();
            });

            $form.attr('action', s.url).append(s.file).submit();
        });
    };
})(jQuery); 
//and this is how to use the script
(function($){$(document).ready(function(){
    $('input[type="submit"]').click(function(){
        $('input[type="file"]').each(function(){
            $.iframeUpload({
                url: 'http://example.com/upload.php',
                file: this,
                success: function(){
                    console.log('uploaded');
                }
            });
       });
    }); 
})})(jQuery);   
</script>
</head>
<body>   
    <!-- here are multiple files -->
    <input type="file" name="file" />
    <input type="file" name="file" />
    <input type="file" name="file" /> 
    <!-- to upload -->
    <input type="submit" />
</body>
</html>

答案 4 :(得分:0)

通过从A Strategy for Handling Multiple File Uploads Using Javascript处的代码开始,我能够做到这一点。该代码为每个文件使用XMLHttpRequest,但实际上不检查服务器的结果。我对其进行了修改,以按顺序等待服务器的结果,如下所示:

var fileNumber = 0
var fileList = []    // see the code linked above for how to handle the fileList
var resultPane = document.getElementById('resultpane')   // a textarea box

sendNext = function() {
  if (fileNumber >= fileList.length) {
    resultPane.value += 'Done uploading '+fileNumber+' files\n'
    return 0
  }
  var formData = new FormData()
  var request = new XMLHttpRequest()
  request.onreadystatechange = function() {
    if (request.readystate == XMLHttpRequest.DONE) {
      resultPane.value += request.responseText    // show whatever the server said about each file
      sendNext()                                  // and send the next file
    }
  }
  formData.set('file', fileList[fileNumber])
  request.open('POST', 'https://example.com/upload-receiver')
  request.send(formData)
  resultPane.value += 'Sending file number '+fileNumber+'\n'
  fileNumber++
}