Comment puis-je attraper jQuery $.getJSON (ou $.ajax avec datatype défini à' jsonp') erreur lors de l'utilisation de JSONP?

est-il possible de détecter une erreur en utilisant JSONP avec jQuery? J'ai essayé les deux sur le $.getJSON et $.méthodes ajax mais ni l'un ni l'autre ne va attraper l'erreur 404 que je teste. Voici ce que j'ai essayé (gardez à l'esprit que tout fonctionne correctement, mais je veux traiter le cas lorsqu'il échoue):

jQuery.ajax({
    type: "GET",
    url: handlerURL,
    dataType: "jsonp",
    success: function(results){
        alert("Success!");
    },
    error: function(XMLHttpRequest, textStatus, errorThrown){
        alert("Error");
    }
});

et aussi:

jQuery.getJSON(handlerURL + "&callback=?", 
    function(jsonResult){
        alert("Success!");
    });

j'ai aussi essayé d'ajouter le $.ajaxError mais cela n'a pas fonctionné non plus:

jQuery(document).ajaxError(function(event, request, settings){
   alert("Error");
});

Merci d'avance pour toutes les réponses!

74
demandé sur Andy May 2008-11-21 22:48:35

10 réponses

il semble que les requêtes JSONP qui ne renvoient pas un résultat positif ne déclenchent jamais d'événement, de succès ou d'échec, et pour le meilleur ou pour le pire, c'est apparemment de par leur conception.

après avoir cherché leur traceur de bogues, il y a un patch qui peut être une solution possible en utilisant un rappel de délai. Voir rapport de bogue n ° 3442 . Si vous ne pouvez pas capturer l'erreur, vous pouvez au moins timeout après avoir attendu une quantité raisonnable de temps pour succès.

52
répondu Adam Bellaire 2008-11-21 20:27:54

Ici 's ma longue réponse à une question similaire.

voici le code:

jQuery.getJSON(handlerURL + "&callback=?", 
    function(jsonResult){
        alert("Success!");
    })
.done(function() { alert('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { alert('getJSON request failed! ' + textStatus); })
.always(function() { alert('getJSON request ended!'); });
48
répondu user2314737 2017-05-23 12:03:06

Détection de la JSONP problèmes

Si vous ne voulez pas télécharger une dépendance, vous pouvez détecter l'état d'erreur vous-même. Il est facile.

vous ne pourrez détecter les erreurs JSONP qu'en utilisant une sorte de timeout. S'il n'y a pas de réponse valide dans un certain temps, alors supposez une erreur. L'erreur pourrait être fondamentalement quelque chose, bien que.

Voici une façon simple de vérifier les erreurs. Il suffit d'utiliser un success drapeau:

var success = false;

$.getJSON(url, function(json) {
    success = true;
    // ... whatever else your callback needs to do ...
});

// Set a 5-second (or however long you want) timeout to check for errors
setTimeout(function() {
    if (!success)
    {
        // Handle error accordingly
        alert("Houston, we have a problem.");
    }
}, 5000);

comme thedawnrider mentionné dans les commentaires, vous pouvez également utiliser clearTimeout à la place:

var errorTimeout = setTimeout(function() {
    if (!success)
    {
        // Handle error accordingly
        alert("Houston, we have a problem.");
    }
}, 5000);

$.getJSON(url, function(json) {
    clearTimeout(errorTimeout);
    // ... whatever else your callback needs to do ...
});

pourquoi? Lire sur...


Voici comment JSONP fonctionne en un mot:

JSONP n'utilise pas XMLHttpRequest comme les requêtes AJAX régulières. Au lieu de cela, il injecte une balise <script> dans la page, où l'attribut "src" est L'URL de la requête. Le contenu de la réponse est enveloppée dans une fonction Javascript qui est ensuite exécutée lors du téléchargement.

par exemple.

demande JSONP: https://api.site.com/endpoint?this=that&callback=myFunc

Javascript injectera cette balise de script dans le DOM:

<script src="https://api.site.com/endpoint?this=that&callback=myFunc"></script>

que se passe-t-il lorsqu'une étiquette <script> est ajoutée au DOM? Évidemment, il est exécuté.

supposons donc la réponse à cette question produit un résultat JSON comme:

{"answer":42}

au navigateur, c'est la même chose que la source d'un script, donc il est exécuté. Mais que se passe-t-il quand vous exécutez ceci:

<script>{"answer":42}</script>

Eh bien, rien. C'est juste un objet. Elle n'est pas stockée, sauvegardée, et rien ne se passe.

c'est pourquoi JSONP demande d'envelopper leurs résultats dans une fonction. Le serveur, qui doit prendre en charge la sérialisation JSONP, voit le callback paramètre spécifié et renvoie plutôt ceci:

myFunc({"answer":42})

puis ceci est exécuté à la place:

<script>myFunc({"answer":42})</script>

... qui est beaucoup plus utile. Quelque part dans votre code, dans ce cas, une fonction globale appelée myFunc :

myFunc(data)
{
    alert("The answer to life, the universe, and everything is: " + data.answer);
}

C'est ça. C'est la" magie " de JSONP. Ensuite, pour construire une vérification de timeout est très simple, comme montré ci-dessus. Faites la requête et immédiatement après, démarrez un timeout. Après X secondes, si votre drapeau n'a toujours pas été activé, alors la requête s'est éteinte.

15
répondu Matt 2013-01-15 19:07:51

je sais que cette question est un peu vieille mais je n'ai pas vu de réponse qui donne une solution simple au problème donc j'ai pensé que je partagerais ma solution "simple".

$.getJSON("example.json", function() {
      console.log( "success" );
}).fail(function() { 
      console.log( "error" ); 
}); 

nous pouvons simplement utiliser le rappel .fail() pour vérifier si une erreur s'est produite.

Espérons que cela aide :)

13
répondu Farhan Ahmad 2013-09-05 15:46:45

si vous collaborez avec le fournisseur, vous pouvez envoyer un autre paramètre de chaîne de requête étant la fonction pour rappeler quand il y a une erreur.

?rappel=?&erreur=?

cela s'appelle JSONPE mais ce n'est pas du tout une norme de facto.

Le fournisseur transmet ensuite l'information à la fonction d'erreur pour vous aider à diagnostiquer.

N'aide pas avec les erreurs comm cependant - jQuery devrait être mis à jour pour rappelez aussi la fonction d'erreur sur timeout, comme dans la réponse D'Adam Bellaire.

3
répondu delitescere 2010-06-05 20:06:55

semble que cela fonctionne maintenant:

jQuery(document).ajaxError(function(event, request, settings){
   alert("Error");
});
2
répondu Fhansen 2011-08-17 04:07:05

j'utilise ceci pour attraper une erreur JSON

try {
   $.getJSON(ajaxURL,callback).ajaxError();
} catch(err) {
   alert("wow");
   alert("Error : "+ err);
}

Edit: alternativement vous pouvez obtenir le message d'erreur aussi. Cela vous permettra de savoir quelle est l'erreur exactement. Essayez la syntaxe suivante dans le bloc de saisie

alert("Error : " + err);
1
répondu tomjshore 2012-06-22 19:33:47

Mayby ceci fonctionne?

.complete(function(response, status) {
    if (response.status == "404")
        alert("404 Error");
    else{
        //Do something
    }   
    if(status == "error")
        alert("Error");
    else{
        //Do something
    }
});

Je ne sais pas quand l'état va en mode" erreur". Mais je l'ai testé avec 404 et il a répondu

0
répondu Marcel 2012-09-13 13:13:34

vous pouvez explicitement gérer n'importe quel numéro d'erreur en ajoutant Cet attribut dans la requête ajax:

statusCode: {
        404: function() {
          alert("page not found");
        }
    }

ainsi, votre code devrait être comme ceci:

jQuery.ajax({
type: "GET",
statusCode: {
        404: function() {
          alert("page not found");
        }
},
url: handlerURL,
dataType: "jsonp",
success: function(results){
    alert("Success!");
},
error: function(XMLHttpRequest, textStatus, errorThrown){
    alert("Error");
}
});

espère que cela vous aide :)

0
répondu ghost rider3 2013-08-02 14:01:49

j'ai aussi posté cette réponse dans stack overflow - traitement des erreurs dans les appels getJSON 151990920"

je sais que ça fait longtemps que quelqu'un a répondu ici et que l'affiche a probablement déjà reçu sa réponse d'ici ou d'ailleurs. Je pense cependant que ce post aidera quiconque cherche un moyen de garder une trace des erreurs et des temps morts tout en faisant des requêtes getJSON. Donc ci-dessous ma réponse à la question

la structure de 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 comme un endroit pour ajouter le "?callback=?" et d'autres variables qui doivent être envoyés pour obtenir les données JSON correctes retournés, et la fonction de succès comme une fonction pour le traitement des données.

vous pouvez cependant ajouter les variables statut et xhr dans votre fonction de succès. La variable status contient l'une des chaînes suivantes : "success", "notmodified", "error", "timeout", ou "parsererror", et la variable xhr contient L'objet XMLHttpRequest retourné ( 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 garder la trace des temps morts et des erreurs sans avoir à mettre en œuvre un tracker de temps mort personnalisé qui est lancé une fois qu'une demande est faite.

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

0
répondu Tom Groentjes 2017-05-23 12:26:23