30

複数のファイルのアップロードフォームがあります:

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

これらのファイルをajaxで投稿しています。選択したファイルを1つずつアップロードしたいと思います(個々のプログレスバーを作成するため、そして不思議なことに)。

ファイルまたは個々のファイルのリストは、次の方法で取得できます。

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

イーリング

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

しかし、FileListは不変であり、単一のファイルを送信する方法がわかりません。

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

4

5 に答える 5

32

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

したがって、それぞれ$.ajax()の後に、サーバー側(何を使用するかはわかりません)で、JSON応答を送信して、次の入力でAJAXを実行します。success1つのオプションは、AJAX要素を各要素にバインドして、作業を簡単にすることです。これにより、で行うことができます$(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 
于 2012-12-03T21:45:08.443 に答える
8

これは非常に優れたチュートリアルのように見えます。まさにあなたが探しているものです

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

私はいつもこのスクリプトを使用していて、非常に簡潔だと思います。iframeを作成してアップロードする方法を学びたい場合は、そのソースを掘り下げる必要があります。

それが役に立てば幸い :)

追加編集

iframeメソッドでプログレスバーを作成するには、サーバー側でいくつかの作業を行う必要があります。phpを使用している場合は、次を使用できます。

nginxを使用する場合は、アップロード進行状況モジュールを使用してコンパイルすることもできます

これらはすべて同じように機能します。すべてのアップロードにはUIDがあり、ajaxを介して一定の間隔でそのIDに関連付けられた「進行状況」を要求します。これにより、サーバーによって決定されたアップロードの進行状況が返されます。

于 2012-12-03T22:21:36.800 に答える
5

私は同じ問題に直面していて、この解決策を思いついた。私は単にマルチパートでフォームを取得し、再帰呼び出し(ファイルごとに)で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 );
    }
}
于 2015-02-07T22:42:15.540 に答える
1

このソースコードを使用すると、ajaxを介してグーグルのような複数のファイルを1つずつアップロードできます。また、アップロードの進行状況を確認できます

HTML

 <input type="file" id="multiupload" name="uploadFiledd[]" multiple >
 <button type="button" id="upcvr" class="btn btn-primary">Start Upload</button>
 <div id="uploadsts"></div>

Javascript

<script>

function uploadajax(ttl,cl){

var fileList = $('#multiupload').prop("files");
$('#prog'+cl).removeClass('loading-prep').addClass('upload-image');

var form_data =  "";

form_data = new FormData();
form_data.append("upload_image", fileList[cl]);


var request = $.ajax({
          url: "upload.php",
          cache: false,
          contentType: false,
          processData: false,
          async: true,
          data: form_data,
          type: 'POST', 
          xhr: function() {  
      var xhr = $.ajaxSettings.xhr();
      if(xhr.upload){ 
        xhr.upload.addEventListener('progress', function(event){
                        var percent = 0;
                        if (event.lengthComputable) {
                            percent = Math.ceil(event.loaded / event.total * 100);
                        }
                        $('#prog'+cl).text(percent+'%')

                    }, false);
       }
      return xhr;
     }    
      })
      .success(function(res,status) {

        if(status == 'success'){

            percent = 0;
            $('#prog'+cl).text('');            

                $('#prog'+cl).text('--Success: ');

            if(cl < ttl){
                uploadajax(ttl,cl+1);
            }else{
               alert('Done ');

            }     

            }

      })
      .fail(function(res) {
      alert('Failed');
      });

}



$('#upcvr').click(function(){

var fileList = $('#multiupload').prop("files");
$('#uploadsts').html('');
var i
for ( i = 0; i < fileList.length; i++) {
$('#uploadsts').append('<p class="upload-page">'+fileList[i].name+'<span class="loading-prep" id="prog'+i+'"></span></p>');
if(i == fileList.length-1){
    uploadajax(fileList.length-1,0);
}
}

});

</script>

PHP

upload.php
    move_uploaded_file($_FILES["upload_image"]["tmp_name"],$_FILES["upload_image"]["name"]);
于 2018-08-04T10:59:17.283 に答える
0

HTMLコード

<div class="row">
    <form id="singleUploadForm" name="singleUploadForm" style="float: right; padding-right: 25px">
        <input style="float: left;" id="singleFileUploadInput" type="file" name="files" class="file-input btn btn-default" required multiple/>
        <button style="float: left" type="submit" class="btn .btn-primary">Upload</button>
    </form>
</div>

JavaScriptコード

$('#mutipleUploadForm').submit(function (event) {
    var formElement = this;
    var formData = new FormData(formElement);
    $.ajax({
        type: "POST",
        enctype: 'multipart/form-data',
        url: "/uploadFile",
        data: formData,
        processData: false,
        contentType: false,
        success: function (response) {
            alert("Image Uploaded Successfully");

            location.reload();
        },
        error: function (error) {
            console.log(error);
            // process error
        }
    });
    event.preventDefault();
});

スプリングコントローラークラス

@PostMapping("/uploadFile")
@ResponseBody
public boolean uploadMutipleFiles(@RequestParam("file") MultipartFile[] file) {
    List<Boolean> uploadStatusList = new ArrayList<>();
    for (MultipartFile f : file) {
        uploadStatusList.add(uploadFile(f));
    }
    return !uploadStatusList.contains(false);
}

public boolean uploadFile(@RequestParam("file") MultipartFile file) {
    boolean uploadStatus = galleryService.storeFile(file);
    return uploadStatus;
}

春のサービスクラス

public boolean storeFile(MultipartFile file) {
    boolean uploadStatus = false;
    try {
        String fileName = file.getOriginalFilename();
        InputStream is = file.getInputStream();
        Files.copy(is, Paths.get(imagesDirectory + fileName), StandardCopyOption.REPLACE_EXISTING);
        System.out.println("File store success");
        uploadStatus = true;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return uploadStatus;
}
于 2019-10-11T09:42:45.550 に答える