web-dev-qa-db-fra.com

Traitement des erreurs dans les appels getJSON

Comment pouvez-vous gérer les erreurs dans un appel getJSON? J'essaie de référencer un service de script interdomaine à l'aide de jsonp, comment enregistrez-vous une méthode d'erreur?

182
Ajay

$.getJSON() est une sorte d'abstraction d'un appel normal AJAX dans lequel vous devez indiquer que vous souhaitez une réponse codée JSON.

$.ajax({
  url: url,
  dataType: 'json',
  data: data,
  success: callback
});

Vous pouvez gérer les erreurs de deux manières: de manière générique (en configurant vos appels AJAX avant de les appeler réellement) ou spécifiquement (avec une chaîne de méthodes).

"générique" serait quelque chose comme:

$.ajaxSetup({
      "error":function() { alert("error");  }
});

Et la manière "spécifique":

$.getJSON("example.json", function() {
  alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })
.complete(function() { alert("complete"); });
272
Luciano Costa

Quelqu'un a donné ces points à Luciano :) Je viens de tester sa réponse (une question similaire) et j'ai parfaitement fonctionné ...

J'ajoute même mes 50 centimes:

.error(function(jqXHR, textStatus, errorThrown) {
        console.log("error " + textStatus);
        console.log("incoming Text " + jqXHR.responseText);
    })
82
frenetix

Voici mon ajout.

De http://www.learnjavascript.co.uk/jq/reference/ajax/getjson.html et la source officielle

" Les méthodes de rappel jqXHR.success (), jqXHR.error () et jqXHR.complete () introduites dans jQuery 1.5 sont obsolètes à partir de jQuery 1.8. Pour préparer votre code en vue de leur suppression éventuelle , utilisez plutôt jqXHR.done (), jqXHR.fail () et jqXHR.always (). "

Je l'ai fait et voici l'extrait de code mis à jour de Luciano:

$.getJSON("example.json", function() {
  alert("success");
})
.done(function() { alert('getJSON request succeeded!'); })
.fail(function() { alert('getJSON request failed! '); })
.always(function() { alert('getJSON request ended!'); });

Et avec la description de l'erreur et l'affichage de toutes les données JSON sous forme de chaîne:

$.getJSON("example.json", function(data) {
  alert(JSON.stringify(data));
})
.done(function() { alert('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { alert('getJSON request failed! ' + textStatus); })
.always(function() { alert('getJSON request ended!'); });

Si vous n'aimez pas les alertes, remplacez-les par console.log

$.getJSON("example.json", function(data) {
  console.log(JSON.stringify(data));
})
.done(function() { console.log('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { console.log('getJSON request failed! ' + textStatus); })
.always(function() { console.log('getJSON request ended!'); });
63
user2314737

Je sais que cela fait un moment que quelqu'un a répondu ici et que l'affiche l'a probablement déjà reçue soit d'ici, soit d'ailleurs. Cependant, je pense que cet article aidera tous ceux qui cherchent un moyen de suivre les erreurs et les délais d’exécution des requêtes getJSON. Donc ci-dessous ma réponse à la question

La structure getJSON est la suivante (trouvée sur http://api.jqueri.com ):

$(selector).getJSON(url,data,success(data,status,xhr))

la plupart des gens mettent en œuvre que l'utilisation

$.getJSON(url, datatosend, function(data){
    //do something with the data
});

où ils utilisent l'URL var pour fournir un lien vers les données JSON, le datatosend en tant qu'emplacement pour ajouter le "?callback=?" et d'autres variables à envoyer pour obtenir les données JSON correctes renvoyées, et la fonction de succès en tant que fonction de traitement des données.

Vous pouvez cependant ajouter les variables status et xhr dans votre fonction de réussite. La variable status contient l'une des chaînes suivantes: "success", "notmodified", "error", "timeout" ou "parsererror", et la variable xhr contient l'objet XMLHttpRequest renvoyé ( trouvé sur w3schools =)

$.getJSON(url, datatosend, function(data, status, xhr){
    if (status == "success"){
        //do something with the data
    }else if (status == "timeout"){
        alert("Something is wrong with the connection");
    }else if (status == "error" || status == "parsererror" ){
        alert("An error occured");
    }else{
        alert("datatosend did not change");
    }         
});

De cette façon, il est facile de suivre les délais et les erreurs sans avoir à implémenter un suivi de dépassement de délai personnalisé qui est démarré une fois la demande effectuée.

J'espère que cela aidera quelqu'un qui cherche encore une réponse à cette question.

12
Tom Groentjes

Il semble qu'il n'y ait pas de méthode d'erreur d'après ce que j'ai lu ici . Cette réponse offre une bonne explication

9
Ben Shelock
$.getJSON("example.json", function() {
  alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })

Il est corrigé dans jQuery 2.x; Dans jQuery 1.x, vous ne recevrez jamais de rappel d'erreur

2
Pavlo O.

Pourquoi pas

getJSON('get.php',{cmd:"1", typeID:$('#typesSelect')},function(data) {
    // ...
});

function getJSON(url,params,callback) {
    return $.getJSON(url,params,callback)
        .fail(function(jqXMLHttpRequest,textStatus,errorThrown) {
            console.dir(jqXMLHttpRequest);
            alert('Ajax data request failed: "'+textStatus+':'+errorThrown+'" - see javascript console for details.');
        })
}

??

Pour plus de détails sur la méthode .fail() utilisée (jQuery 1.5+), voir http://api.jquery.com/jQuery.ajax/#jqXHR

Puisque la jqXHR est renvoyée par la fonction, un chaînage comme

$.when(getJSON(...)).then(function() { ... });

est possible.

1
Blauhirn

J'ai été confronté à ce même problème, mais plutôt que de créer des rappels pour une demande ayant échoué, j'ai simplement renvoyé une erreur avec l'objet de données json.

Si possible, cela semble être la solution la plus simple. Voici un exemple du code Python que j'ai utilisé. (Utilisation de Flask, jsonify f et SQLAlchemy de Flask)

try:
    snip = Snip.query.filter_by(user_id=current_user.get_id(), id=snip_id).first()
    db.session.delete(snip)
    db.session.commit()
    return jsonify(success=True)
except Exception, e:
    logging.debug(e)
    return jsonify(error="Sorry, we couldn't delete that clip.")

Ensuite, vous pouvez vérifier sur Javascript comme ceci;

$.getJSON('/ajax/deleteSnip/' + data_id,
    function(data){
    console.log(data);
    if (data.success === true) {
       console.log("successfully deleted snip");
       $('.snippet[data-id="' + data_id + '"]').slideUp();
    }
    else {
       //only shows if the data object was returned
    }
});
1
Nick Woodhams

Dans certains cas, vous pouvez rencontrer un problème de synchronisation avec cette méthode. J'ai écrit l'appel de rappel dans une fonction setTimeout, et cela a fonctionné de manière synchrone très bien =)

PAR EXEMPLE:

function obterJson(callback) {


    jqxhr = $.getJSON(window.location.href + "js/data.json", function(data) {

    setTimeout(function(){
        callback(data);
    },0);
}
0
Alex Alonso