2012-12-01 91 views
24

をアップロード私は複数のファイルの形式をアップロード持っている:HTML5複数のファイルのアップロード:AJAXを1つずつ

<input type="file" name="files" multiple /> 

私はAjaxで、これらのファイルを掲示しています。選択したファイルを1つずつアップロードしたいと思います(個別の進行状況バーを作成し、不思議ではありません)。

私は

FileList { 0=File, 1=File, length=2 } 
File { size=177676, type="image/jpeg", name="img.jpg", more...} 

をyieling

FL = form.find('[type="file"]')[0].files 
F = form.find('[type="file"]')[0].files[0] 

によってファイルや個々のファイルのリストを取得することができますが、ファイルリストは不変であると私は1つのファイルを提出する方法を見つけ出すことはできません。

これは、私がhttp://blueimp.github.com/jQuery-File-Upload/を見たときに可能だと思います。私はこのプラグインを使用したくないのですが、結果として学習するのと同じくらい(そして、とにかくあまりにも多くのcustimizingが必要になります)。私はまた、Flashを使いたくない。

答えて

26

これを同期動作にするには、最後の転送が完了したら新しい転送を開始する必要があります。たとえば、Gmailはすべてを一度に同時に送信します。 AJAXファイルアップロードの進捗状況は、XmlHttpRequestインスタンスのprogressまたはonprogressです。

したがって、サーバー側(私はあなたが何を使用するのか分かりません)で、次の入力時にAJAXを実行するためのJSON応答を送信します。 1つのオプションは、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 

上記のコードは、複数の<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 
+4

このコードがのみいるFormDataとXmlHttpRequest2をサポート本当に最近のブラウザのために意図されていること、ノート、それはとてもおいしそうなぜ、古いブラウザ – pocesar

+4

のためのハックが...不思議なかった;) – Selosindis

+5

は新しい「フォーム」を作成し、追加します(新しいFormData())を使用してファイルを1つずつ追加します。append( 'file'、this.files [count]) 'は私が探していたものでした。 – Mark

7

This looks like a very good tutorial, just what you're looking for

これは、すべてのブラウザでvanilla ajaxによるアップロードがサポートされているわけではありませんが、まだiframeを使用することをおすすめします。 (I.Eは動的にiframeを作成し、javascriptを使用してPOSTします)

I have always been using this scriptと私は非常に簡潔です。 iframeを作成してアップロードする方法を知りたい場合は、そのソースを参照する必要があります。

はそれが役に立てば幸い:) iframeの方法で

エクストラ編集

作成するには、プログレスバーを、あなたはいくつかの仕事のサーバー側を行う必要があります。あなたがPHPを使用している場合は、使用することができます:PHP < 5用php5.4 +

  • Upload progress packageため

    使用nginxのは、あなたがまた、これらのすべてが同じように動作し、そのUpload progress module

    を使用してコンパイルすることを選択できる場合 - すべてのアップロードがUIDを持っている、あなたはでそのIDに関連付けられている「進歩」のために要求されます一貫した間隔でajax経由でこれにより、サーバーによって決定されたアップロードの進行状況が返されます。

  • +0

    最初のリンクは確かにFormDataオブジェクトについての良いチュートリアルでした、ありがとう! – Mark

    1

    私は同じ問題に直面していて、この解決策がありました。私は単純にマルチパートでフォームを取得し、再帰呼び出し(ファイルの後のファイル)では、ajaxリクエストを開始します。

    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); 
        } 
    } 
    
    +0

    これは尋ねられたものではありません。 OPは、選択されたファイルを個々の進捗バーと共に1つずつアップロードするように頼んだ。 Downvoted。 – TheCarver

    関連する問題