76 votes

Comment éviter l'erreur jQuery $.getJSON (ou $.ajax avec le type de données défini sur 'jsonp') lorsque j'utilise JSONP ?

Est-il possible d'attraper une erreur en utilisant JSONP avec jQuery ? J'ai essayé les méthodes $.getJSON et $.ajax, mais aucune ne permet de détecter l'erreur 404 que je teste. Voici ce que j'ai essayé (gardez à l'esprit que tout cela fonctionne avec succès, mais je veux gérer le cas où cela é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 é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 !

52voto

user2314737 Points 1671

Ici Voici ma réponse détaillée à 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!'); });

51voto

Adam Bellaire Points 42797

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

Après avoir cherché dans leur bug tracker, il y a un patch ce qui peut être une solution possible en utilisant un callback de dépassement de temps. Voir rapport de bogue #3442 . Si vous ne pouvez pas capturer l'erreur, vous pouvez au moins demander un délai d'expiration après avoir attendu un temps raisonnable pour le succès.

16voto

Matt Points 5202

Détection des problèmes JSONP

Si vous ne voulez pas télécharger une dépendance, vous pouvez détecter l'état d'erreur vous-même. C'est très simple.

Vous ne serez en mesure de 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 au bout d'un certain temps, il y aura une erreur. L'erreur peut être n'importe quoi, cependant.

Voici une méthode simple pour 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 l'a mentionné thedawnrider 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 ? Lisez la suite...


Voici comment fonctionne JSONP en quelques mots :

JSONP n'utilise pas XMLHttpRequest comme les requêtes AJAX ordinaires. Au lieu de cela, il injecte un <script> 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 va injecter cette balise script dans le DOM :

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

Que se passe-t-il lorsqu'un <script> est ajouté au DOM ? Évidemment, elle est exécutée.

Supposons que la réponse à cette requête donne un résultat JSON du type :

{"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 quand vous exécutez ceci :

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

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

C'est pourquoi les requêtes JSONP enveloppent leurs résultats dans une fonction. Le serveur, qui doit supporter la sérialisation JSONP, voit la fonction callback que vous avez spécifié, et renvoie ceci à la place :

myFunc({"answer":42})

Alors ceci est exécuté à 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 tout. C'est la "magie" de JSONP. Il est ensuite très simple d'intégrer une vérification du délai d'attente, comme indiqué ci-dessus. Faites la demande et immédiatement après, lancez un délai d'attente. Au bout de X secondes, si votre drapeau n'a toujours pas été activé, cela signifie que la demande a expiré.

11voto

livedo Points 765

Un URI fonctionnel pour la solution de Julian pour JSON-P avec jQuery est le suivant https://github.com/jaubourg/jquery-jsonp

3voto

delitescere Points 230

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

?callback=?&error= ?

C'est ce qu'on appelle JSONPE, mais il ne s'agit pas du tout d'une norme de facto.

Le fournisseur transmet ensuite des informations à la fonction d'erreur pour vous aider à établir un diagnostic.

Cela n'aide pas pour les erreurs de communication - jQuery devrait être mis à jour pour rappeler la fonction d'erreur au bout du compte, comme dans la réponse d'Adam Bellaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X