2
function makeCall(file, handlerFile, sendMethod, formData) {
    //console.log(instance.files);

    $.ajax({
        url: handlerFile,
        type: sendMethod,
        xhr: function() {  // Custom XMLHttpRequest
            var xhr = $.ajaxSettings.xhr();

            if(xhr.upload) { // Check if upload property exists
                xhr.upload.addEventListener('progress', progressHandlingFunction.bind(file)); // For handling the progress of the upload
                //xhr.upload.addEventListener('loadend', successHandler.bind(xhr));
            }

            //console.log(xhr);

            return xhr;
        },
        beforeSend: beforeSendHandler.bind(file),
        success: completeHandler.bind(file),
        //error: errorHandler,
        data: formData, // Form data
        dataType: 'json',
        cache: true,
        //async: false,
        contentType: false,
        processData: false
    });

}



$(".afu-input").on('change', function() {
        var i = 0;
        var length = this.files.length;
        var files = this.files;

        var calling = setInterval(function() {
            var file = files[i];
            console.log(file);

            uid  = generateUniqueId();
            file.id = uid;

            var formData = null;
            formData = new FormData();

            formData.append(i, file);
            formData.append(i, [uid]);

            makeCall(file, handlerFile, sendMethod, formData);

            i++;

            if (i >= length) {
                clearInterval(calling);
            }
        }, 2000); // Delay is for testing. Normaly there is no delay
}

ファイルを1つずつアップロードしようとしています。しかし、問題は ajax がリクエストを適切に送信することですが、返されるデータは 1 つ (最初) だけです。

私の目標は、input[type=file] の変更時に画像 (および後で他のファイル) をアップロードするスクリプトを作成することです。1回のリクエストで複数のファイルをアップロードしようとしたのですが、進行イベントが1つとして登録されてしまいます。ファイルを断片にスライス (チャンク) して送信することを考えていましたが、このバリアントの方が簡単に思えます (機能させるだけでよいので、改善します)。ありがとう。

4

1 に答える 1

5

jQuery.when();で簡単に作成できます。

Ajax 呼び出しは任意の番号にすることができます。したがって、apply(); で使用する必要があります。ajax呼び出しの配列を作成します。コードは次のようになります。

function makeCall(file, formData) {
    return $.ajax({ // It's necessary to return ajax call 
       url: 'handler.php',
       type: 'POST',
       xhr: function() { // Creating custom XHR to register progress event(If you know better solution - please post ir)
           var xhr = $.ajaxSettings.xhr();

           if (xhr.upload) { // Check if upload property exists
               xhr.upload.addEventListener('progress', progressHandlingFunction.bind(file)); // Registering progress event
           }

           return xhr;
       },
       // Events handlers
       beforeSend: beforeSendHandler.bind(file),
       success: completeHandler,
       data: formData,
       dataType: 'json',
       cache: true,
       contentType: false,
       proccessData: false
    });
}

$('.afu-input').on('change', function() {
    var files = this.files;
    var calls = [];

    $.each(files, function(i, file) {
        uid = generateUniqueId();
        file.id = uid;

        var formData = new formData();

        formData.append(0, file); // Just easier to set index to 0 cause for every file returning new obejct, so is no point to set more indexes

        calls.push(makeCall(file, formData)); // And finally pushing calls to array
    });

    // Using jQuery.when
    // Cause I don't know how many calls will be I'm using "apply" so I can add array instead of one by one calls
    $.when.apply($, calls); // Exactly I don't know why need "$"
}

function beforeSendHandler() {
    console.log(this);
}

function completeHandler(data) {
    console.log(data);
}

function progressHandlingFunction(e) {
    console.log(e);
    console.log(this);
}
于 2013-10-25T14:09:45.427 に答える