web-dev-qa-db-fra.com

XMLHttpRequest appelle toujours l'écouteur d'événement "load", même lorsque la réponse a un statut d'erreur

J'utilise FormData pour ajax un téléchargement de fichier. Le téléchargement fonctionne, mais le problème est que le rappel "d'erreur" n'est jamais appelé. Même lorsque ma réponse HTTP est une erreur de serveur interne 500 (pour tester ce serveur I Tweak afin de répondre avec 500), le rappel "load" est appelé.

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

Des idées? Je teste ceci sur Chrome.

23
Ben Simmons

Cette configuration devrait mieux fonctionner pour vos besoins:

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

Dans votre code d'erreur, le rappel d'erreur n'est jamais appelé car il est uniquement déclenché par des erreurs au niveau du réseau. Il ignore les codes de retour HTTP.

22
Joe

L'événement de chargement est appelé chaque fois que le serveur répond avec un message. La sémantique de la réponse importe peu; l'important est que le serveur ait répondu (dans ce cas avec un statut 500). Si vous souhaitez appliquer une sémantique d'erreur à l'événement, vous devez traiter vous-même le statut.

8
rich remer
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 de EJS d'après l'exemple de code il est clair que l'erreur réseau n'a pas de réponse, il déclenche un événement d'erreur. événement déclencheur de chargement de la réponse et vous devez décider quoi faire avec l'état de la réponse

0
黃聖琪

En développant la réponse de @rich remer, voici comment accéder au statut vous-même:

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

Veuillez noter l'accès à la propriété e.currentTarget.status de l'événement response (e). On dirait que le statut est réellement disponible via l'un des e.{currentTarget,target,srcElement}.status - je ne suis pas sûr de savoir lequel devrait être utilisé comme meilleure pratique, cependant.

0
jkukul