XMLHttpRequest is always calling “load” event list

2020-05-30 02:56发布

I'm using FormData to ajax a file upload. The upload works, but the problem is that the "error" callback is never invoked. Even when my HTTP response is a 500 internal server error (to test this I tweak server to respond with 500), the "load" callback is invoked.

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);
}

Any ideas? I'm testing this on Chrome.

4条回答
不美不萌又怎样
2楼-- · 2020-05-30 03:32

This setup should work better for your needs:

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);

In your code error callback is never called because it is only triggered by network-level errors, it ignores HTTP return codes.

查看更多
孤傲高冷的网名
3楼-- · 2020-05-30 03:32
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);
 });
}

code from EJS by the example code it is clear that network error has no response, it trigger error event. response trigger load event and you have to decide what to do with the response status

查看更多
迷人小祖宗
4楼-- · 2020-05-30 03:40

The load event is called whenever the server responds with a message. The semantics of the response don't matter; what's important is that the server responded (in this case with a 500 status). If you wish to apply error semantics to the event, you have to process the status yourself.

查看更多
ら.Afraid
5楼-- · 2020-05-30 03:41

Expanding on @rich remer's answer, here's how you could access the status yourself:

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);
}

Please note accessing of the e.currentTarget.status property of the response event (e). Looks like the status is actually available via any of e.{currentTarget,target,srcElement}.status - I'm not sure which one should be used as the best practice, though.

查看更多
登录 后发表回答