web-dev-qa-db-fra.com

Comment puis-je intercepter l'erreur jQuery $ .getJSON (ou $ .ajax avec le type de données défini sur 'jsonp') lors de l'utilisation de JSONP?

Est-il possible de détecter une erreur lors de l'utilisation de JSONP avec jQuery? J'ai essayé les méthodes $ .getJSON et $ .ajax, mais aucune ne détectera l'erreur 404 que je teste. Voici ce que j'ai essayé (gardez à l'esprit que tout cela fonctionne correctement, mais je veux gérer le cas en cas d'échec):

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 également 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 toute réponse!

75
Andy May

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

Après avoir recherché leur traqueur de bogues, il y a n patch qui peut être une solution possible en utilisant un rappel de timeout. Voir rapport de bug # 3442 . Si vous ne pouvez pas capturer l'erreur, vous pouvez au moins expirer après avoir attendu un temps raisonnable pour réussir.

51
Adam Bellaire

Ici est ma réponse complète à 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!'); });
52
user2314737

Détection des problèmes JSONP

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

Vous ne pourrez détecter les erreurs JSONP qu'en utilisant une sorte de délai d'attente. S'il n'y a pas de réponse valide dans un certain temps, supposez une erreur. L'erreur pourrait être essentiellement n'importe quoi, cependant.

Voici un moyen simple de vérifier les erreurs. Utilisez simplement un indicateur success:

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 l'a mentionné l'aube 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? Continuer à lire...


Voici comment JSONP fonctionne en bref:

JSONP n'utilise pas XMLHttpRequest comme les AJAX requêtes régulières. Au lieu de cela, il injecte un <script> balise dans la page, où l'attribut "src" est l'URL de la demande. Le contenu de la réponse est enveloppé 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 quand un <script> la balise est ajoutée au DOM? De toute évidence, il est exécuté.

Supposons donc que la réponse à cette requête ait donné un résultat JSON comme:

{"answer":42}

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

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

Eh bien, rien. Ce n'est qu'un objet. Il n'est pas stocké, enregistré et rien ne se passe.

C'est pourquoi les requêtes JSONP encapsulent leurs résultats dans une fonction. Le serveur, qui doit prendre en charge la sérialisation JSONP, voit le paramètre callback que vous avez spécifié et le renvoie à la place:

myFunc({"answer":42})

Ensuite, cela s'exécute à la place:

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

... ce qui est beaucoup plus utile. Quelque part dans votre code se trouve, 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. Il est alors très simple de créer un contrôle de délai d'attente, comme illustré ci-dessus. Faites la demande et immédiatement après, démarrez une temporisation. Après X secondes, si votre indicateur n'est toujours pas défini, la demande a expiré.

16
Matt

Je sais que cette question est un peu ancienne mais je n'ai pas vu de réponse qui donne une solution simple au problème, alors 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.

J'espère que cela t'aides :)

14
Farhan Ahmad

Si vous collaborez avec le fournisseur, vous pouvez envoyer un autre paramètre de chaîne de requête servant de fonction de rappel en cas d'erreur.

? callback =? & error =?

C'est ce qu'on appelle JSONPE mais ce n'est pas du tout une norme de facto.

Le fournisseur transmet ensuite des informations à la fonction d'erreur pour vous aider à diagnostiquer.

N'aide pas cependant avec les erreurs de communication - jQuery devrait être mis à jour pour rappeler également la fonction d'erreur à l'expiration, comme dans la réponse d'Adam Bellaire.

3
delitescere

Il semble que cela fonctionne maintenant:

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

J'utilise ceci pour attraper une erreur JSON

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

Edit: Alternativement, vous pouvez également obtenir le message d'erreur. Cela vous permettra de savoir exactement quelle est l'erreur. Essayez de suivre la syntaxe dans le bloc catch

alert("Error : " + err);
1
tomjshore

vous pouvez gérer explicitement tout numéro d'erreur en ajoutant cet attribut dans la demande ajax:

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

donc, 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");
}
});

j'espère que cela vous aide :)

0
ghost rider3

Peut-être que cela 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 passe en mode "erreur". Mais je l'ai testé avec 404 et il répond

0
Marcel

J'ai également posté cette réponse dans stack overflow - Gestion des erreurs dans les appels getJSON

Je sais que cela fait un moment que quelqu'un n'a pas répondu ici et l'affiche a probablement déjà obtenu sa réponse d'ici ou d'ailleurs. Je pense cependant que ce message aidera toute personne à la recherche d'un moyen de garder une trace des erreurs et des délais d'attente lors de la demande de 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 cette utilisation

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

où ils utilisent la var url 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ées pour obtenir les données JSON correctes retournées, et la fonction de réussite en tant que fonction de traitement des données.

Vous pouvez cependant ajouter les variables status et xhr dans votre fonction success. La variable d'état 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 garder une trace des délais d'attente et des erreurs sans avoir à implémenter un suivi de délai d'attente personnalisé qui démarre une fois qu'une demande est effectuée.

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

0
Tom Groentjes