web-dev-qa-db-ja.com

XHRアップロードの進行状況は最初から100%です

新しいXMLHTTPRequestUpload機能を試し、いくつかのファイルをphpスクリプトにアップロードしようとしていますが、ほとんど正常に機能し、アップロードが開始され、終了応答が返されますが、進行状況が機能していないようです。

Event.loadedの値を見る-Firefoxでは、0からファイルサイズまでのランダムな値を取得しているようです。 in Chrome(私が主に作業している場所)readystateが「4」に達していないにもかかわらず、開発者ツールウィンドウにロード中のファイルが表示されているにもかかわらず、合計ファイルサイズを取得しますか?

何か案は?

これが私のコードです:

var xhr = new XMLHttpRequest()

xhr.upload.addEventListener('progress', function(event) {
    if (event.lengthComputable) {
        $('ajaxFeedbackDiv').innerHTML = event.loaded + ' / ' + event.total;
    }
}, false);

xhr.onreadystatechange = function(event) {
    if (event.target.readyState == 4) {
        updateFileList();
    }
};

xhr.open("POST", "_code/upload.php");
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.setRequestHeader("X-File-Size", file.size);
xhr.setRequestHeader("X-File-Type", file.type);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr(file);

どうもありがとう

ベン

24
Ben Robinson

また、最近、XHRの進行中のイベントのイベントリスナーを設定するのにいくつかの問題がありました。私はそれを匿名関数として実装することになりました。これは美しく機能します。

xhr.upload.onprogress = function(evt)
{
    if (evt.lengthComputable)
    {
        var percentComplete = parseInt((evt.loaded / evt.total) * 100);
        console.log("Upload: " + percentComplete + "% complete")
    }
};

しかし、途中で他の落とし穴lotに出くわしたので、そのうちの1つが私のイベントリスナーをつまずかせていた可能性があります。あなたがそこに持っているものと私のセットアップとの間の他の唯一の違いは、私がxhr.sendAsBinary()を使用しているということです。

23
R Hill

私自身も同様の問題に遭遇しました。そこでは、progressXMLHttpRequestイベントのイベントハンドラー関数が、アップロードが完了したときに1回だけ実行されました。

問題の原因は単純でした-Google Chrome(おそらく他のブラウザも、私はテストしませんでした)では、progressイベントは次の場合にのみ連続して発生しますアップロードは1、2秒実行されていました。つまり、アップロードがすぐに終了した場合は、100%progressイベントが1つだけ発生する可能性があります。

progressイベントが100%完了したときに1回だけ発生するコードの例を次に示します( https://jsfiddle.net/qahs40r6/ ):

$.ajax({
  xhr: function()
  {
    var xhr = new window.XMLHttpRequest();
    //Upload progress
    xhr.upload.addEventListener("progress", function(evt){
      if (evt.lengthComputable) {
        var percentComplete = evt.loaded / evt.total;
        console.log("Upload ", Math.round(percentComplete*100) + "% complete.");
      }
    }, false);
    return xhr;
  },
  type: 'POST',
  url: "/echo/json/",
  data: {json: JSON.stringify(new Array(20000))}
});

コンソール出力:

Upload  100% complete.

ただし、配列のサイズにゼロを追加すると(ペイロードサイズが10倍に増加します-- https://jsfiddle.net/qahs40r6/1/ ):

$.ajax({
  xhr: function()
  {
    var xhr = new window.XMLHttpRequest();
    //Upload progress
    xhr.upload.addEventListener("progress", function(evt){
      if (evt.lengthComputable) {
        var percentComplete = evt.loaded / evt.total;
        console.log("Upload ", Math.round(percentComplete*100) + "% complete.");
      }
    }, false);
    return xhr;
  },
  type: 'POST',
  url: "/echo/json/",
  data: {json: JSON.stringify(new Array(200000))}
});

次に、progressイベントの通常の進行を取得します。

Upload  8% complete.
Upload  9% complete.
Upload  19% complete.
Upload  39% complete.
Upload  50% complete.
Upload  81% complete.
Upload  85% complete.
Upload  89% complete.
Upload  100% complete.

この動作はインターネット接続の速度に依存するため、マイレージは異なります。たとえば、最初の例を取り上げ、Chrome Developer Toolsを使用して、シミュレートされた「Slow 3G」への接続を遅くすると、一連のprogressイベントが表示されます。

同様に、ローカルで開発していて、ローカルWebサーバーにデータをアップロードしている場合、アップロードはすぐに終了するため、progressイベントは表示されない可能性があります。これは、@ brettjonesdevがローカルホストとリモート製品の展開で見たものである可能性があります。

6
Elliot B.