Comment rappeler une fonction sur 404 dans JSON ajax request avec jQuery?

je veux faire une demande Ajax avec réponse dans JSON. J'ai donc fait cette demande Ajax:

$.ajax({
    url: 'http://my_url',
    dataType: "json",
    success: function(data){
      alert('success');
    },
    error: function(data){
      alert('error');
    },
    complete: function(data) {
      alert('complete')
    }})

ce code fonctionne bien mais lorsque mon url m'envoie un code HTTP 404, aucun callback n'est utilisé, même le callback complet. Après recherche, c'est parce que mon type de données est "json" donc 404 retour est HTML et le JSON parsing échoué. Donc, pas de rappel.

avez-vous une solution pour appeler une fonction de rappel quand un 404 est soulevé ?

Modifier: callback complet ne pas appeler est de retour est de 404. Si vous voulez une URL avec 404 vous pouvez appeler: http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697 c'est avec cette URL que j'ai mon problème.

21
demandé sur jao 2010-03-22 19:31:16

10 réponses

$.ajax({
    url: 'http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697',
    dataType: "json",
    success: function(data) {
        alert('success');
    },
    error: function(data) {
        alert('error');
    },
    complete: function(xhr, data) {
        if (xhr.status != 0)
             alert('success');
        else
             alert('fail');
    }
})
19
répondu Dustin Laine 2014-12-09 12:23:57

avec votre configuration jQuery utilise jsonp pour transporter les données. Cela fonctionne en insérant dynamiquement un élément de script et en définissant L'URL à la valeur spécifiée. Les données retournées par le serveur sont alors évaluées en JavaScript - appelant habituellement le rappel fourni. Si le serveur renvoie un 404, le contenu n'est évidemment pas JavaScript et le rappel n'est jamais appelé. Certains navigateurs prennent en charge les gestionnaires d'erreurs sur la balise script, qui sont appelés situation. Malheureusement IE ne supporte pas cela. La meilleure façon de détecter une erreur est de compter sur un délai d'attente.

dans votre cas, vous devez spécifier une option supplémentaire timeout , qui provoque l'appel du gestionnaire d'erreurs si le rappel n'a pas été appelé à temps (ce qui serait le cas pour une réponse 404).

$.ajax({
  url: 'http://my_url',
  timeout: 2000, // 2 seconds timeout
  dataType: "json",
  success: function(data){
    alert('success');
  },
  error: function(data){
    alert('error');
  },
  complete: function(data) {
    alert('complete')
  }
});
9
répondu Fabian Jakobs 2010-03-29 11:44:12

si vous souhaitez gérer les erreurs lors de l'accès à L'API Twitter avec Javascript et jsonp, vous devez inclure le paramètre suppress_response_codes dans votre demande. Cela fait toutes les réponses de L'API Twitter répondre avec une réponse 200 OK et inclure une erreur. Ensuite, vous devez vérifier si la réponse inclut ou non le paramètre error .

$.ajax({
  url: "https://api.twitter.com/1/users/show.json",
  dataType: 'jsonp',
  jsonp: "callback",
  data: {
    screen_name: "simongate1337",
    suppress_response_codes: true // <- Important part
  },
  success: function(data) {
    if(data.error) {
      console.log("ERROR: "+data.error);
    } else {
      console.log("Success, got user " + data.screen_name);
    }
  }
});
4
répondu Simon Gate 2012-08-23 13:49:02

utiliser le statusCode - Option

$.ajax({
    url: 'http://my_url',
    dataType: "json",
    statusCode: {
        404: function() {
            alert("I could not find the information you requested.");
        }
    },
    success: function(data) {
      alert('success');
    },
    error: function(data) {
      alert('error');
    },
    complete: function(data) {
      alert('complete');
    }
})
3
répondu Peter Rader 2018-07-10 23:26:29

Ne pensez-vous pas que le problème n'est pas avec le type de données, mais avec des requêtes inter-domaine que vous n'êtes pas autorisé à faire?

le code ci-dessous fonctionne comme prévu lorsque vous demandez des données à partir du même domaine et ne fonctionne pas lorsque vous faites des requêtes inter-domaines:

function handle404(xhr){
    alert('404 not found');
}

function handleError(xhr, status, exc) {
     // 0 for cross-domain requests in FF and security exception in IE 
    alert(xhr.status);
    switch (xhr.status) {
        case 404:
            handle404(xhr);
            break;
    }
}

function dumbRequest() {
    var url = 'http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697';
    url = 'http://twitter.com/';    
    url = '/mydata.json';    
//    url = 'mydata.json';    
    $.ajax(
        {url: url,
         dataType: 'json',
         error: handleError}
    );
}
2
répondu newtover 2010-04-01 07:52:35

est-ce simplement parce que le dataType est réglé sur"json"? Si c'est le cas, essayez de le remplacer par text et évaluez vous-même le JSON:

$.ajax({
    url: 'http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697',
    dataType: 'text',
    success: function(data, status, xmlHttp) {
        try {
            data = eval('(' + data + ')');
            alert('success');
        } catch (e) {
            alert('json parse error');
        }
    },
    error: function(xmlHttp, status, error) {
        alert('error');
    },
    complete: function(xmlHttp, status) {
        alert('complete');
    }
});
1
répondu Matt Huggins 2010-03-29 07:26:17

êtes-vous conscient que même si le statut HTTP est 404, le corps réel est valide JSON? Par exemple, ce lien a le JSON suivant:

jsonp1269278524295({"request":"/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697","error":"Not found"})

en tant que tel, vous devriez vérifier si vos données ont la propriété error dans votre fonction de rappel normale.

UPDATE : apparemment, même si le contenu réel de la page est valide JSON, le navigateur (I vérifié dans Firefox) ne l'exécute pas, très probablement parce que c'est un 404. Parce que jQuery doit ajouter un élément script (en raison de la question transversale), son enveloppeur JSONP n'est jamais appelé, et par conséquent, vos callbacks ne le sont pas non plus.

donc, en résumé, je ne pense pas qu'il y ait un moyen de gérer cela sans ajouter manuellement cet élément de script et vérifier si votre fonction de rappel prédéfinie a été appelée après.

1
répondu janmoesen 2010-04-02 20:05:14

Juste face à la même question, et vu une autre question mentionné que jQuery-JSONP (Plugin jQuery) prend en charge la capture des erreurs 404 ou qu'ils décrivent: " erreur de récupération en cas de défaillance du réseau ou mal formé réponses JSON"

Et il fonctionne parfaitement :)

Voici mon code (simplifié) pour récupérer des détails sur une vidéo YouTube via JSONP:

$.jsonp(
{
    url: "https://gdata.youtube.com/feeds/api/videos/ee925OTFBCA",
    callbackParameter: "callback",
    data: 
    {
        alt: "jsonc-in-script",
        v: "2"
    },
    success: function(json, textStatus) 
    { 
        console.log("WEEEEEEEE!"); 
    },
    error: function(xOptions, textStatus) 
    {
        console.error(arguments);
    }
});
1
répondu Mark K 2017-05-23 10:31:25

voilà comment je gère ça. J'ai vérifier les données renvoyées pour les erreurs avant d'essayer de l'utiliser. Ce qui est montré ci-dessous est juste un échantillon que vous pourriez étendre pour plus étroitement correspondre à vos besoins. Cela tient également compte des périodes de session et d'autres scénarios...

mon appel initial:

  $.ajax({ type: 'POST', 
    url: '../doSomething',
    data: 'my data',
    success: function(data) {
      if (HasErrors(data)) return;
      var info = eval('(' + data + ')');
      // do what you want with the info object
    },
    error: function(xmlHttpRequest) {
      ReportFailure(xmlHttpRequest);
    }
  });

et les deux fonctions d'aide:

function HasErrors(data) {
  if (data.search(/login\.aspx/i) != -1) {
    // timed out and being redirected to login page!
    top.location.href = '../login.aspx';
    return true;
  }
  if (data.search(/Internal Server Error/) != -1) {
    ShowStatusFailed('Server Error.');
    return true;
  }
  if (data.search(/Error.aspx/) != -1) {
    // being redirected to site error reporting page...
    ShowStatusFailed('Server Error. Please try again.');
    return true;
  }
  return false;
}

et

function ReportFailure(msg) {
  var text;
  if (typeof msg == 'string') {
    text = msg;
  }
  else if (typeof msg.statusText == 'string') {
    if (msg.status == 200) {
      text = msg.responseText;
    }
    else {
      text = '(' + msg.status + ') ' + msg.statusText + ': ';
      // use the Title from the error response if possible
      var matches = msg.responseText.match(/\<title\>(.*?)\<\/title\>/i);
      if (matches != null)
      { text = text + matches[1]; }
      else
      { text = text + msg.responseText; }
    }
  }
  // do something in your page to show the "text" error message
  $('#statusDisplay')
    .html('<span class="ui-icon ui-icon-alert"></span>' + text)
    .addClass('StatusError');
}
0
répondu Glen Little 2010-04-03 17:37:22

la solution suivante fonctionne très bien pour moi:)

$.ajax({
    url: 'http://my_url',
    dataType: "json",
    success: function(data){
      alert('success');
    },
    error: function(data){
      alert('error');
    },complete: function(xhr, data) {
        if(data==="parsererror"){
             alert('404');
        }
    } 
});
0
répondu Awan 2012-04-07 15:33:34