web-dev-qa-db-ja.com

応答にエラーステータスがある場合でも、XMLHttpRequestは常に「ロード」イベントリスナーを呼び出します

私はFormDataを使用してファイルのアップロードをajaxしています。アップロードは機能しますが、問題は「エラー」コールバックが呼び出されないことです。 HTTP応答が500内部サーバーエラーである場合でも(これをテストして500で応答するようにサーバーを調整します)、 "load"コールバックが呼び出されます。

function upload_image() {
    var form = document.getElementById('upload_image_form');
    var formData = new FormData(form);

    var xhr = new XMLHttpRequest();
    xhr.addEventListener("load", function(e) {
        alert("Success callback");
    }, false);
    xhr.addEventListener("error", function(e) {
        alert("Error callback");
    }, false);
    xhr.open("POST", "/upload_image");
    xhr.send(formData);
}

何か案は?これをChromeでテストしています。

25
Ben Simmons

この設定はあなたのニーズによりよく働くはずです:

var req = new XMLHttpRequest();
req.open('POST', '/upload_image');
req.onreadystatechange = function (aEvt) {
  if (req.readyState == 4) {
     if(req.status == 200)
      alert(req.responseText);
     else
      alert("Error loading page\n");
  }
};
req.send(formData);

コードエラーコールバックは、ネットワークレベルのエラーによってのみトリガーされるため、呼び出されることはなく、HTTPリターンコードを無視します。

25
Joe

Loadイベントは、サーバーがメッセージで応答するたびに呼び出されます。応答のセマンティクスは重要ではありません。重要なのは、サーバーが応答したことです(この場合は500ステータス)。イベントにエラーセマンティクスを適用する場合は、ステータスを自分で処理する必要があります。

8
rich remer

@rich remerの答えを拡張して、自分でステータスにアクセスする方法を次に示します。

function upload_image() {
    var form = document.getElementById('upload_image_form');
    var formData = new FormData(form);

    var xhr = new XMLHttpRequest();
    xhr.addEventListener("load", function(e) {
        if(e.currentTarget.status < 400)
            alert("Load callback - success!");
        else
            alert("Load callback - error!");
    }, false);
    xhr.addEventListener("error", function(e) {
        alert("Error callback");
    }, false);
    xhr.open("POST", "/upload_image");
    xhr.send(formData);
}

応答イベント(e)のe.currentTarget.statusプロパティへのアクセスに注意してください。ステータスは実際にはe.{currentTarget,target,srcElement}.statusのいずれかを介して利用できるようです。ただし、どれをベストプラクティスとして使用すればよいかわかりません。

1
Jakub Kukul
function get(url) {
return new Promise(function(succeed, fail) {
  var req = new XMLHttpRequest();
  req.open("GET", url, true);
  req.addEventListener("load", function() {
    if (req.status < 400)
      succeed(req.responseText);
    else
      fail(new Error("Request failed: " + req.statusText));
  });
  req.addEventListener("error", function() {
    fail(new Error("Network error"));
  });
  req.send(null);
 });
}

EJSからのコード サンプルコードから、ネットワークエラーに応答がないことが明らかであり、エラーイベントをトリガーします。応答トリガーロードイベント。応答ステータスをどうするかを決定する必要があります。

0
黃聖琪