最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - Javascript Multiple File Upload, Sequentially One at a Time - Stack Overflow

programmeradmin2浏览0评论

We have a form with five <input type="file"/> elements that is in production and working great. We get request timeouts and MaxRequestLength exceeded errors on occasion. To prevent these errors, I planned to write some Javascript to upload the files one-at-a-time instead of all at once. Here is how I planned on doing this...

  1. On document.ready, inject a hidden iframe into page
  2. Change the <form> to target the iframe
  3. Disable all elements on the form (which prevents them from being POSTed)
  4. Enable one file-upload at a time and submit the form
  5. Wait for the response from the server
  6. When server response is printed into iframe, start the next upload
  7. When all uploads are done, refresh the page, which will invoke some server-side logic that populates a grid.

My problem is with number 5. Normally I think I could figure this out no problem, but I am just having one of those days where my brain is on strike. Here is my code thus far...

$(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);
  });
});

What kind of construct do I need here in order to "wait" for the server response before kicking off the next upload?

We have a form with five <input type="file"/> elements that is in production and working great. We get request timeouts and MaxRequestLength exceeded errors on occasion. To prevent these errors, I planned to write some Javascript to upload the files one-at-a-time instead of all at once. Here is how I planned on doing this...

  1. On document.ready, inject a hidden iframe into page
  2. Change the <form> to target the iframe
  3. Disable all elements on the form (which prevents them from being POSTed)
  4. Enable one file-upload at a time and submit the form
  5. Wait for the response from the server
  6. When server response is printed into iframe, start the next upload
  7. When all uploads are done, refresh the page, which will invoke some server-side logic that populates a grid.

My problem is with number 5. Normally I think I could figure this out no problem, but I am just having one of those days where my brain is on strike. Here is my code thus far...

$(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);
  });
});

What kind of construct do I need here in order to "wait" for the server response before kicking off the next upload?

Share Improve this question edited Dec 23, 2009 at 15:28 Josh Stodola asked Dec 2, 2009 at 15:02 Josh StodolaJosh Stodola 82.6k48 gold badges186 silver badges229 bronze badges 6
  • I should note that I want to write this code myself, not use some fancy plugin with a bunch of dependencies. – Josh Stodola Commented Dec 2, 2009 at 15:09
  • If this bee too much of a pain, I might just try to use use five iframes! That's the last thing I want to do, but it might be what I have to do. – Josh Stodola Commented Dec 2, 2009 at 15:19
  • 1 @Stodola Nobody wants anything to do with flash' is really subjective. What is your problem with Flash? I was trying to give you more information regarding Uploadify. ' I dont understand why you want to reinvent something that already works perfectly if you just look around for other solutions that exist. – Josh Mein Commented Dec 23, 2009 at 15:25
  • @jmein Flash is third-party. It does not work on 64-bits. It has a dependency. It's annoying. It's inaccessible. It has security problems. Call it subjective all you want; nobody I know would ever use it in a production scenario. It's a toy for children. – Josh Stodola Commented Dec 23, 2009 at 15:30
  • @JoshStdolla Then why does Hulu work on my 64 bit machine? Hulu uses flash. – Bryan Denny Commented Dec 23, 2009 at 15:36
 |  Show 1 more ment

5 Answers 5

Reset to default 2

I've had a lot of success lately using Uploadify--it's very configurable, free, and allows for multiple-uploads. It also provides the option for callback functions allowing you to really configure it any way you want.

http://www.uploadify./

I think you should listen for iframe's load event and perform input's switching in the handler. I pleted with my own uploader today and this solution worked for me.

Just FYI: jquery.forms plugin is all about making ajax form submitions. I use this plugin to submit a form (such as a file upload) in a separate iframe which the plugin takes care of automatically, and gives you a nice callback when pleting.

This way most work for you is done.

http://jquery.malsup./form/

It can be done with the help of jQuery's queue method and load event.

<!DOCTYPE HTML>
<html>
<head>
<script src="http://ajax.googleapis./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./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>

I was able to do this, by starting with the code at A Strategy for Handling Multiple File Uploads Using Javascript. That code uses an XMLHttpRequest for each file, but actually doesn't check the result from the server. I modified it to wait for the result from the server, sequentially, as follows:

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./upload-receiver')
  request.send(formData)
  resultPane.value += 'Sending file number '+fileNumber+'\n'
  fileNumber++
}
发布评论

评论列表(0)

  1. 暂无评论