21

ファイルのアップロードに ajax を使用しています。ファイルがアップロードされた後、php はそれをチェックする必要があります (mime、サイズ、ウイルス (clamscan) など) - 大きなファイルの場合、これには数秒かかります。ファイルのアップロード中に HTML5<progress>が読み込まれます。ファイルの準備が整い、PHP がチェックを開始すると、進行状況は不確定に切り替わるはずです。これを行う方法を考えました(どちらも機能しませ):

upload.onload イベントの確認

xhr.upload.addEventListener("load", function (e) {
    $("#uploadprogress").attr("value", false);
    $("#uploadprogress").attr("max", false);
    $("#progress").text("Checking file...");
});

onloadアップロードの準備ができたときではなく、リクエストの準備ができたときにイベントが発生するため、これは機能しません。

アップロードの進捗率 = 100% かどうかの確認

xhr.upload.addEventListener("progress", function (e) {
    if (e.lengthComputable && e) {
        p = (e.loaded / e.total);
        if (p==1) {
            $("#uploadprogress").attr("value", false);
            $("#uploadprogress").attr("max", false);
            $("#progress").text("Checking file...");
        } else {
            var percent = Math.ceil(p * 1000) / 10;
            $("#uploadprogress").val(e.loaded);
            $("#uploadprogress").attr("max", e.total);
            $("#progress").text("Uploading... " + percent + "%");
        }
   }
}
});

これは機能しません。アップロードが完了し、PHP がファイルの処理を開始したにもかかわらず、97%

これをチェックする別の可能性はありますか?

4

4 に答える 4

55

リッスンするイベントはreadystatechange、XHR オブジェクト (XHR.upload ではありません) にあります。readyStateアップロードの送信が4完了 、サーバーが接続を閉じたときです。loadend/loadサーバーが接続を閉じるかどうかに関係なく、アップロードが完了したときに発生します。参考までに、リッスンできるイベントとそれらが発生するタイミングを次に示します。

    var xhr = new XMLHttpRequest();

    // ...
    // do stuff with xhr
    // ...

    xhr.upload.addEventListener('loadstart', function(e) {
      // When the request starts.
    });
    xhr.upload.addEventListener('progress', function(e) {
      // While sending and loading data.
    });
    xhr.upload.addEventListener('load', function(e) {
      // When the request has *successfully* completed.
      // Even if the server hasn't responded that it finished.
    });
    xhr.upload.addEventListener('loadend', function(e) {
      // When the request has completed (either in success or failure).
      // Just like 'load', even if the server hasn't 
      // responded that it finished processing the request.
    });
    xhr.upload.addEventListener('error', function(e) {
      // When the request has failed.
    });
    xhr.upload.addEventListener('abort', function(e) {
      // When the request has been aborted. 
      // For instance, by invoking the abort() method.
    });
    xhr.upload.addEventListener('timeout', function(e) {
      // When the author specified timeout has passed 
      // before the request could complete.
    });

    // notice that the event handler is on xhr and not xhr.upload
    xhr.addEventListener('readystatechange', function(e) {
      if( this.readyState === 4 ) {
        // the transfer has completed and the server closed the connection.
      }
    });
于 2013-03-19T03:40:22.137 に答える
3

https://bugzilla.mozilla.org/show_bug.cgi?id=637002に基づきます。

完全な動作例を見てみましょう...

// YOUR (SIMPLE) JAVASCRIPT FILE
var form = new FormData(), xhr = new XMLHttpRequest();
form.append('inputname', YOURFILE);

xhr.open('POST', 'http://oneserver/onephpfile', true);
xhr.setRequestHeader('X-CSRF-Token', 'somestring');
xhr.onreadystatechange = function () {
    if ((xhr.readyState === 4) && (xhr.status === 200))
        // do other thing with xhr.responseText.trim()
};

xhr.upload.addEventListener('loadstart', showProgressBarFunction, false);
xhr.upload.addEventListener('progress',  updateProgressBarFunction, false);
xhr.upload.addEventListener('load',      updateProgressBarFunction, false);
xhr.send(form);

// YOUR FIRST (SIMPLE) PHP FILE
header('Content-Type: text/plain; charset=utf-8');
header('Cache-Control: no-cache, must-revalidate');

sleep(20);
echo 'file processing ended';

この最初の PHP ファイルでは、次のように表示されますただし、次のように表示されます: 10%... 50%... 75%... 100%... Chrome/Chromium (33/37) および Opera (24) で「他のことを行う」。

// YOUR SECOND (SIMPLE) PHP FILE
header('Content-Encoding: chunked', true);
header('Content-Type: text/plain; charset=utf-8');
header('Cache-Control: no-cache, must-revalidate');
ini_set('output_buffering', false);
ini_set('implicit_flush', true);
ob_implicit_flush(true);
for ($i = 0; $i < ob_get_level(); $i++)
    ob_end_clean();
echo ' ';

sleep(20);
echo 'file processing ended';

この 2 番目の PHP ファイルでは、10%... 50%... 75%... 100%... Chrome/Chromium (33/37/53)、Opera (24 /42)、Firefox (4/10/28/32/45)、IE (10/11)、Edge (14)!

于 2014-09-14T17:24:59.240 に答える
1

これは、timeRemaining や transferSpeed などの情報を追加するために簡単に拡張できた hTML5 仕様の比較的よく知られている失敗です。

formath.roundの代わりに使用して、数 % のポイントをオフにするのに役立つ少しあいまいさを焼き付けることを検討しましたか?math.ceilvar percent

バックエンドで完了しているにもかかわらず、UI が 100% 未満で停止する場合は、loadComplete の別のリスナーも追加する必要があります。

//only fires once
xhr.addEventListener('loadend', uploadComplete, false);
function uploadComplete(event) {
    console.log('rejoice...for I have completed');
    //do stuff
}
于 2013-03-19T00:52:24.607 に答える
0

readyStateを確認し、if(readyState==4) {//it has finished, put code here}

于 2013-03-20T09:08:25.417 に答える