web-dev-qa-db-fra.com

Comment déclencher un rappel d'erreur jquery.ajax () basé sur la réponse du serveur, pas HTTP 500?

En utilisant la fonction jquery ajax, je peux faire quelque chose comme:

$.ajax({

  url: url,
  type: 'GET',
  async: true,
  dataType: 'json',
  data: data,

 success: function(data) {

     //Handle server response here

  },

 error: function(xhr, status, error){

    //Handle failure here

 }

});

J'ai deux questions à poser sur la base du code ci-dessus:

  1. Quand le rappel jquery.ajax () error sera-t-il appelé ??

  2. Que faire si le serveur me répond un objet json avec un message de chaîne " Il y a une erreur ". Ce qui signifie que la demande est toujours envoyée avec succès, mais j'ai reçu la réponse du serveur {message: "There is an error"}.

Je pense que peu importe quelle valeur de chaîne le serveur est répondu, si le client obtient la réponse du serveur, le rappel jquery.ajax ()success sera déclenché de toute façon.

Je voudrais demander si le serveur me renvoie spécifiquement un objet JSON avec une valeur de chaîne comme {message: 'There is an error'}, le serveur pourrait-il faire quelque chose pour que cette réponse soit gérée dans jquery.ajax ()error callback au lieu de success callback?

40
Leem

Le rappel d'erreur sera exécuté lorsque la réponse du serveur ne sera pas celle que vous attendiez. Ainsi, par exemple dans ces situations, il:

  • HTTP 404/500 ou tout autre message d'erreur HTTP a été reçu
  • des données de type incorrect ont été reçues (c'est-à-dire que vous vous attendiez à JSON, vous avez reçu autre chose).

Dans votre situation, les données sont correctes (c'est un message JSON). Si vous souhaitez déclencher manuellement le rappel d'erreur en fonction de la valeur des données reçues, vous pouvez le faire assez simplement. Modifiez simplement le rappel anonyme pour l'erreur en fonction nommée.

function handleError(xhr, status, error){

    //Handle failure here

 }

$.ajax({

  url: url,
  type: 'GET',
  async: true,
  dataType: 'json',
  data: data,

 success: function(data) {
     if (whatever) {
         handleError(xhr, status, ''); // manually trigger callback
     }
     //Handle server response here

  },

 error: handleError
});
31
RaYell

Nous supposons que le serveur envoie du JSON, et en cas de succès de la requête, nous obtiendrons quelque chose comme ceci:

{
    success: true,
    data: {
        name: 'Foo'
    }
}

... et en cas d'échec:

{
    success: false,
    error: 'Something bad happened.'
}

Ensuite, nous filtrons simplement la réponse avec un $. Deferred :

$.get('http://localhost/api').then(function(res) {
    var filter = $.Deferred();

    if (res.success) {
        filter.resolve(res.data);
    } else {
        filter.reject(res.error);
    }

    return filter.promise();
}).done(function(data) {
    console.log('Name:',  data.name); // Outputs: Foo
}).fail(function(error) {
    console.log('Error:', error); // Outputs: Something bad happened.
})
26
Simen Brekken

Le rappel d'erreur est pour quand l'aller-retour Ajax n'a pas pu être terminé avec succès, pas quelque chose basé sur la logique de votre serveur. Il serait de votre responsabilité de vérifier ce que vous considérez comme une réponse réussie dans le rappel de réussite. c'est-à-dire ajouter un seul IF conditionnel qui vérifie si le message = "Il y a eu une erreur." et y inclure votre logique d'erreur, sinon faites la logique de réussite.

Une approche pour faire ce que vous demandez serait que le serveur retourne un en-tête 404 en cas d'erreur, il serait alors géré par le rappel d'erreur. Le problème avec cette approche est que vous vous cacheriez en cas d'erreurs réelles et que vous ne seriez pas en mesure de transmettre des données supplémentaires avec.

3
Fosco

La chose la plus simple à faire serait de restructurer comme suit:

function handleAjaxError function(xhr, status, error) {
    //Handle failure here
}

$.ajax({
  url: url,
  type: 'GET',
  async: true,
  dataType: 'json',
  data: data,

  success: function(data) {

     //Handle server response here
    if (data.message == 'There is an error')
    {
        handleAjaxError();
        return;
    }

    //... all is good....

  },
  error: handleAjaxError
});
2
Gary Green

Cette question originale a été publiée il y a des années, et il y a peut-être de meilleures façons de gérer cela maintenant. Voici une suggestion pour gérer plusieurs types d'erreurs, y compris la question de l'OP.

Exemple de type d'entrée (erreur) # 1

function handleError (type){
type = type || "Connection Issue";
 var value = "Error occurred: " + type;
 alert(value);
}

function checkIfError(response){
    if (response == "DB_ERROR") {
        handleError("Server error");
        throw new Error("JS died"); // optional, keep from running additional script
     }
}

var example = {

    success: function (response) {
        checkIfError(response); // check data if error msg
        // do stuff when proper data sent
        alert(response);

    }, error: handleError // connection error, call error msg
};

test1 = example['error']();

Exemple de type d'entrée (succès: erreur) # 2

function handleError (type){
type = type || "Connection Issue";
 var value = "Error occurred: " + type;
 alert(value);
}

function checkIfError(response){
    if (response == "DB_ERROR") {
        handleError("Server error");
        throw new Error("JS died"); // optional, keep from running additional script
     }
}

var example = {

    success: function (response) {
        checkIfError(response); // check data if error msg
        // do stuff when proper data sent
        alert(response);

    }, error: handleError // connection error, call error msg
};


test2 = example['success']("DB_ERROR");

Exemple de type d'entrée (succès) # 3

function handleError (type){
type = type || "Connection Issue";
 var value = "Error occurred: " + type;
 alert(value);
}

function checkIfError(response){
    if (response == "DB_ERROR") {
        handleError("Server error");
        throw new Error("JS died"); // optional, keep from running additional script
     }
}

var example = {

    success: function (response) {
        checkIfError(response); // check data if error msg
        // do stuff when proper data sent
        alert(response);

    }, error: handleError // connection error, call error msg
};


test3 = example['success']("Proper Response");

En utilisant des fonctions, si vous avez plusieurs appels dans vos scripts, vous pouvez simplifier les modifications.

Demandez à votre PHP (ou tout autre code côté serveur) de retourner la réponse de "DB_ERROR" (ou ce que vous voulez) pour déclencher l'erreur; vous permet de faire différentes choses en fonction de l'erreur.

0
Ben in CA

Une façon simple de le faire est d'utiliser simplement la fonction jQuery always () pour votre rappel, puis si vous souhaitez créer manuellement une erreur, profitez simplement de Duck Typing!

Par exemple:

$.get(url, {"data": data}).always(function(result)
{
    if (typeof result.status !== "undefined" && result.status !== 200) // Status code 200 represents Success/OK
    {
        //handle error
        error = "Your error was " + result.status + " " + result.statusText;
    }
    else
    {
        //success
    }
});

La section d'erreur sera toujours exécutée s'il y avait une erreur d'en-tête naturelle telle qu'un 404 Not Found. Si vous souhaitez renvoyer manuellement une erreur, vous pouvez simplement émuler l'objet XHR normalement transmis avec une erreur (par exemple en PHP):

public function ServerSideAjaxResponse($data)
{
    if (!$data)
    {
        $response["status"] = 1001; //Make up your own error codes! Yippee! Fun!
        $response["statusText"] = "Error! You forgot to send the data!";
        echo json_encode($return);
        return;
    }
}
0
dallin