XMLHttpRequest总是调用“load”事件监听器,即使响应有错误状态

时间:2011-07-21 21:30:49

标签: javascript ajax error-handling xmlhttprequest

我正在使用FormData来aj文件上传。上传有效,但问题是永远不会调用“错误”回调。即使我的HTTP响应是500内部服务器错误(为了测试这个我调整服务器以500响应),调用“加载”回调。

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上对此进行测试。

4 个答案:

答案 0 :(得分:24)

此设置应更好地满足您的需求:

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返回码。

答案 1 :(得分:8)

只要服务器响应消息,就会调用load事件。响应的语义无关紧要;重要的是服务器响应(在这种情况下具有500状态)。如果您希望对事件应用错误语义,则必须自己处理状态。

答案 2 :(得分:0)

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 通过示例代码 很明显,网络错误没有响应,它会触发错误事件。 响应触发加载事件 你必须决定如何处理响应状态

答案 3 :(得分:0)

扩展@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.currentTarget.status)的e属性。看起来该状态实际上可以通过e.{currentTarget,target,srcElement}.status中的任何一个获得-尽管我不确定应该使用哪个作为最佳实践。