web-dev-qa-db-fra.com

Gestion des erreurs de requête JSONP

Je fais une demande ajax jsonp, mais la gestion des erreurs d'échec ne fonctionnera pas. Si la demande est 404 ou 500, elle ne traitera pas l'erreur.

J'ai cherché autour de moi pour trouver une réponse à cela, mais je ne trouve rien. Il semble y avoir une solution avec http://code.google.com/p/jquery-jsonp/ , mais je ne trouve aucun exemple sur la façon de l'utiliser.

function authenticate(user, pass) {       
    $.ajax ({
        type: "POST",
        url: "url",
        dataType: 'jsonp',
        async: false,
        //json object to sent to the authentication url
        data: {"u": userid, "p": pass},

        success: function (data) {
            //successful authentication here
            console.log(data);
        },
        error: function(XHR, textStatus, errorThrown) {
            alert("error: " + textStatus);
            alert("error: " + errorThrown);
        }
    })
}
38
Adrian Mojica

Deux façons de gérer les erreurs,

  1. Il n'y a pas de gestion des erreurs pour les demandes JSONP interdomaines. Utilisez le plug-in jsonp disponible sur Github https://github.com/jaubourg/jquery-jsonp qui prend en charge la gestion des erreurs.

  2. jQuery ajax Timeout - Délai d'expiration après un délai raisonnable pour déclencher le rappel d'erreur, car il peut avoir échoué en silence. Vous ne savez peut-être pas quelle était l'erreur réelle (ou l'état de l'erreur), mais au moins vous pouvez gérer l'erreur

36
shyammtp

Si vous cochez documentation jQuery.ajax () , vous pouvez trouver:

erreur

Une fonction à appeler si la requête échoue (...) Remarque : Ce gestionnaire n'est pas appelé pour le script inter-domaine et les requêtes JSONP inter-domaine. Il s'agit d'un événement Ajax.

À cause de cela, vous êtes obligé de trouver une solution de contournement. Vous pouvez spécifier un délai d'expiration pour déclencher un rappel d'erreur. Cela signifie que dans le délai spécifié, la demande doit être traitée avec succès. Sinon, supposez qu'il a échoué:

$.ajax({
    ...
    timeout: 5000, // a lot of time for the request to be successfully completed
    ...
    error: function(x, t, m) {
        if(t==="timeout") {
            // something went wrong (handle it)
        }
    }

});

Autres problèmes dans votre code ...

Alors que JSONP (regardez ici et ici ) peut être utilisé pour surmonter la restriction de la politique d'origine, vous pouvez 't POST using JSONP (voir CORS à la place) car il suffit ne fonctionne pas de cette façon - il crée un élément pour récupérer les données, ce qui doit être fait via une requête GET. La solution JSONP n'utilise pas d'objet XmlHttpRequest, donc ce n'est pas une requête AJAX de la manière standard de compréhension, mais le contenu est toujours accessible dynamiquement - aucune différence pour l'utilisateur final.

$.ajax({
    url: url,
    type: "GET"
    dataType: "jsonp",
    ...

Deuxièmement, vous fournissez des données de manière incorrecte. Vous poussez un objet javascript (créé à l'aide de littéraux d'objet) sur le fil au lieu de sa représentation JSON sérialisée. Créez une chaîne JSON (pas manuellement, utilisez par exemple JSON.stringify convertisseur):

$.ajax({
    ...
    data: JSON.stringify({u: userid, p: pass}),
    ...

Dernier problème, vous avez défini async sur false, tandis que la documentation indique:

Requêtes inter-domaines et dataType: les requêtes "jsonp" ne prennent pas en charge le fonctionnement synchrone.

53
jwaliszko

J'ai du mal comme vous depuis un certain temps à essayer de gérer les erreurs sur les demandes ajax jsonp DataType, mais je veux vous partager mon code, j'espère que cela aide. Une chose de base est d'inclure un délai d'attente sur la demande ajax, sinon il n'entrera jamais l'erreur: fonction

$.ajax({
url: "google.com/api/doesnotexists",
dataType: "jsonp",
timeout: 5000,

success: function (parsed_json) {
console.log(parsed_json);
},

error: function (parsedjson, textStatus, errorThrown) {
console.log("parsedJson: " + JSON.stringify(parsedjson));

$('body').append(
    "parsedJson status: " + parsedjson.status + '</br>' + 
    "errorStatus: " + textStatus + '</br>' + 
    "errorThrown: " + errorThrown);        

 }
});

jsfiddle - Gérer les erreurs avec l'appel ajax jquery et le type de données JSONP - Erreur 404

10
Mikeldi

Je suis en train de construire un projet JS fragile qui utilise jquery-jsonp, et est venu avec une approche dual-jsonp/ajax qui gère les erreurs quelle que soit la méthode utilisée.

function authenticate(user, pass) {
    var ajax = ($.jsonp || $.ajax)({
        'url': /* your auth url */,
        'data': { /* user, pass, ... */ },
        'contentType': "application/javascript",
        'dataType': 'jsonp',
        'callbackParameter': 'callback'  // $.jsonp only; $.ajax uses 'jsonpCallback'
    });
    ajax.done(function (data) {
        // your success events
    });
    ajax.fail(function (jqXHR, textStatus, errorThrown) {
        // $.jsonp calls this func as function (jqXHR, textStatus)
        // and $.ajax calls this func with the given signature
        console.error('AJAX / JSONP ' + textStatus + ': ' +
            (errorThrown || jqXHR.url));
    });
}

Étant donné que jquery-jsonp et $ .ajax prennent en charge la spécification jQuery Deferred, nous pouvons fusionner les deux gestionnaires d'erreurs ensemble, en gérant les erreurs des séries 400 et 500, ainsi que les délais d'attente de recherche.

2
Brian

Vieille question mais j'ai eu le même problème. Voici une solution qui a fonctionné pour moi.

Si vous propre le domaine sur lequel vous envoyez votre demande, vous pouvez définir une variable dans la réponse et la vérifier côté client.

Du côté serveur:

SERVER_RESPONSE=true; Callback(parameter1, parameter2);

Côté client:

if(typeof SERVER_RESPONSE === 'undefined'){
  console.log('No Response, maybe server is down');
}
else{
  console.log('Got a server response');
}
0
Markus