Javascript XMLHttpRequest 始终调用“加载”事件侦听器,即使响应具有错误状态

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6783053/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 23:09:40  来源:igfitidea点击:

XMLHttpRequest is always calling "load" event listener, even when response has error status

javascriptajaxerror-handlingxmlhttprequest

提问by Ben Simmons

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.

我正在使用 FormData 来 ajax 文件上传。上传有效,但问题是“错误”回调从未被调用。即使我的 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);
}

Any ideas? I'm testing this on Chrome.

有任何想法吗?我正在 Chrome 上测试这个。

采纳答案by Joe

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.

在您的代码中,错误回调永远不会被调用,因为它仅由网络级错误触发,它会忽略 HTTP 返回代码。

回答by rich remer

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.

每当服务器响应消息时,就会调用 load 事件。响应的语义无关紧要;重要的是服务器做出响应(在本例中为 500 状态)。如果您希望将错误语义应用于事件,则必须自己处理状态。

回答by Jakub Kukul

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

扩展@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);
}

Please note accessing of the e.currentTarget.statusproperty 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.

请注意访问e.currentTarget.status响应事件 ( e)的属性。看起来状态实际上可以通过任何一个获得e.{currentTarget,target,srcElement}.status- 不过,我不确定应该使用哪一个作为最佳实践。

回答by u5772840

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 EJSby 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

来自EJS的代码通过示例代码很明显网络错误没有响应,它触发了错误事件。响应触发加载事件,您必须决定如何处理响应状态