HTML5多文件上传:通过AJAX逐个上传

Mar*_*ark 29 html ajax jquery file-upload asyncfileupload

我有一个多文件上传表单:

<input type="file" name="files" multiple />
Run Code Online (Sandbox Code Playgroud)

我用ajax发布这些文件.我想逐个上传所选文件(创建单独的进度条,并且出于好奇心).

我可以通过以下方式获取文件列表或单个文件

FL = form.find('[type="file"]')[0].files
F  = form.find('[type="file"]')[0].files[0]
Run Code Online (Sandbox Code Playgroud)

yieling

FileList { 0=File, 1=File, length=2 }
File { size=177676, type="image/jpeg", name="img.jpg", more...}
Run Code Online (Sandbox Code Playgroud)

但FileList是不可变的,我无法弄清楚如何提交单个文件.

我认为这是可能的,因为我看到http://blueimp.github.com/jQuery-File-Upload/.我不想使用这个插件,因为它与学习结果一样多(而且无论如何都需要太多的custimizing).我也不想使用Flash.

poc*_*sar 31

要使其成为同步操作,您需要在完成最后一次操作时启动新传输.例如,Gmail会同时发送所有内容.对AJAX的文件上传进度的事件progressonprogress对原始XmlHttpRequest实例.

因此,在$.ajax()服务器端(我不知道你将使用什么)之后,发送一个JSON响应以在下一个输入上执行AJAX.一种选择是对AJAX元素结合到每一个元素,使事情变得更容易,所以你可以只是做在success$(this).sibling('input').execute_ajax().

像这样的东西:

$('input[type="file"]').on('ajax', function(){
  var $this = $(this);
  $.ajax({
    'type':'POST',
    'data': (new FormData()).append('file', this.files[0]),
    'contentType': false,
    'processData': false,
    'xhr': function() {  
       var xhr = $.ajaxSettings.xhr();
       if(xhr.upload){ 
         xhr.upload.addEventListener('progress', progressbar, false);
       }
       return xhr;
     },
    'success': function(){
       $this.siblings('input[type="file"]:eq(0)').trigger('ajax');
       $this.remove(); // remove the field so the next call won't resend the same field
    }
  });
}).trigger('ajax');  // Execute only the first input[multiple] AJAX, we aren't using $.each
Run Code Online (Sandbox Code Playgroud)

上面的代码是多个<input type="file">但不是<input type="file" multiple>,在这种情况下,它应该是:

var count = 0;

$('input[type="file"]').on('ajax', function(){
  var $this = $(this);
  if (typeof this.files[count] === 'undefined') { return false; }

  $.ajax({
    'type':'POST',
    'data': (new FormData()).append('file', this.files[count]),
    'contentType': false,
    'processData': false,
    'xhr': function() {  
       var xhr = $.ajaxSettings.xhr();
       if(xhr.upload){ 
         xhr.upload.addEventListener('progress', progressbar, false);
       }
       return xhr;
     },
    'success': function(){
       count++;
       $this.trigger('ajax');
    }
  });
}).trigger('ajax'); // Execute only the first input[multiple] AJAX, we aren't using $.each 
Run Code Online (Sandbox Code Playgroud)

  • 创建一个新的'表单'并使用`(new FormData())逐个添加文件.append('file',this.files [count])`就是我想要的,谢谢! (5认同)
  • 请注意,此代码仅适用于仅支持FormData和XmlHttpRequest2的现代浏览器,不适用于旧版浏览器 (4认同)
  • 想知道它为什么看起来那么美味......;) (4认同)
  • 网址在哪里? (2认同)

Nat*_*Kot 8

这看起来像一个非常好的教程,正是您正在寻找的.

注意到,并非所有浏览器都支持通过vanilla ajax上传,我仍然建议使用iframe.(IE动态创建iframe并使用javascript对其进行POST)

我一直在使用这个脚本,我发现它非常简洁.如果您想通过创建iframe了解如何上传,您应该深入了解它的来源.

希望能帮助到你 :)

额外编辑

要使用iframe方法创建进度条,您需要在服务器端执行一些工作.如果你使用的是php,你可以使用:

如果使用nginx,您还可以选择使用他们的上传进度模块进行编译

所有这些都以相同的方式工作 - 每次上传都有一个UID,您将通过ajax以一致的间隔请求与该ID相关联的"进度".这将返回服务器确定的上载进度.


小智 5

我遇到了同样的问题,并提供了这个解决方案。我只是用 multipart 检索表单,并在递归调用(文件后文件)中启动 ajax 请求,它只在完成时调用 next 。

var form = document.getElementById( "uploadForm" );
var fileSelect = document.getElementById( "photos" );
var uploadDiv = document.getElementById( "uploads" );

form.onsubmit = function( event ) {
    event.preventDefault(  );

    var files = fileSelect.files;
    handleFile( files, 0 );
};

function handleFile( files, index ) {
    if( files.length > index ) {
        var formData = new FormData(  );
        var request = new XMLHttpRequest(  );

        formData.append( 'photo', files[ index ] );
        formData.append( 'serial', index );
        formData.append( 'upload_submit', true );

        request.open( 'POST', 'scripts/upload_script.php', true );
        request.onload = function(  ) {
            if ( request.status === 200 ) {
                console.log( "Uploaded" );
                uploadDiv.innerHTML += files[ index ].name + "<br>";
                handleFile( files, ++index );
            } else {
                console.log( "Error" );
            }
        };
        request.send( formData );
    }
}
Run Code Online (Sandbox Code Playgroud)