Error al manejar llamadas getJSON

192

¿Cómo puede manejar los errores en una llamada getJSON? Estoy tratando de hacer referencia a un servicio de script entre dominios utilizando jsonp, ¿cómo se registra un método de error?

Ajay
fuente
Ajay, ¿por qué no considerar marcar la respuesta correcta?
Ionică Bizău
@ IonicăBizău lo marcó ahora. Acabo de perder la pista de esto por un tiempo. La respuesta principal no está hablando de JSONP. Como lo señaló Ben Shelock, no hay un controlador de errores compatible que sea lo que creo ...
Ajay

Respuestas:

277

$.getJSON() es una especie de abstracción de una llamada AJAX normal en la que tendría que decir que desea una respuesta codificada JSON.

$.ajax({
  url: url,
  dataType: 'json',
  data: data,
  success: callback
});

Puede manejar los errores de dos maneras: genéricamente (configurando sus llamadas AJAX antes de llamarlas realmente) o específicamente (con la cadena de métodos).

'genérico' sería algo así como:

$.ajaxSetup({
      "error":function() { alert("error");  }
});

Y la forma 'específica':

$.getJSON("example.json", function() {
  alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })
.complete(function() { alert("complete"); });
Luciano Costa
fuente
Nops! Puedes ir como quieras allí. Eche un vistazo a los documentos para obtener ayuda más detallada: http://api.jquery.com/jQuery.ajax
Luciano Costa
55
Tenga en cuenta que esto requiere jQuery 1.5+ (estaba tratando de hacerlo funcionar con jQuery 1.3 y preguntándose por qué se quejaba de un método no válido :-)
kenyee
24
El OP pregunta específicamente sobre sitios cruzados JSONPen los que parece que getJSONen ese caso no llama a la error()función. Estoy teniendo el mismo problema. Supongo que tiene que ver con cómo JSONPse maneja de manera totalmente diferente a las AJAXllamadas normales a jQuerypesar de getJSONmanejar ambas. JSONse realiza con un XMLHTTPRequestobjeto pero JSONPse agrega dinámicamente una <script>etiqueta a la página HEAD.
hippietrail
3
JQuery Doc dice "Nota: este controlador no se llama para solicitudes de script entre dominios y JSONP". api.jquery.com/jQuery.ajax > error
OneWorld
10
"Los métodos de devolución de llamada jqXHR.success (), jqXHR.error () y jqXHR.complete () introducidos en jQuery 1.5 están en desuso a partir de jQuery 1.8. Para preparar su código para su eventual eliminación, use jqXHR.done (), jqXHR .fail () y jqXHR.always () en su lugar ".
Skorunka František
86

Alguien le da estos puntos a Luciano :) Acabo de probar su respuesta, tenía una pregunta similar, y funcionó perfectamente ...

Incluso agrego mis 50 centavos:

.error(function(jqXHR, textStatus, errorThrown) {
        console.log("error " + textStatus);
        console.log("incoming Text " + jqXHR.responseText);
    })
frenetix
fuente
3
¿Fue esto con JSONP entre sitios o con JSON del mismo sitio?
hippietrail
28
¡Buena respuesta! Solo una nota sobre .error: se desvalorizará en jQuery 1.8, así que use .fail
Anatoly Mironov
73

Aquí está mi adición.

De http://www.learnjavascript.co.uk/jq/reference/ajax/getjson.html y la fuente oficial

" Los métodos de devolución de llamada jqXHR.success (), jqXHR.error () y jqXHR.complete () introducidos en jQuery 1.5 están en desuso a partir de jQuery 1.8. Para preparar su código para su eventual eliminación, use jqXHR.done (), jqXHR .fail () y jqXHR.always () en su lugar " .

Lo hice y aquí está el fragmento de código actualizado de Luciano:

$.getJSON("example.json", function() {
  alert("success");
})
.done(function() { alert('getJSON request succeeded!'); })
.fail(function() { alert('getJSON request failed! '); })
.always(function() { alert('getJSON request ended!'); });

Y con la descripción del error más mostrar todos los datos json como una cadena:

$.getJSON("example.json", function(data) {
  alert(JSON.stringify(data));
})
.done(function() { alert('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { alert('getJSON request failed! ' + textStatus); })
.always(function() { alert('getJSON request ended!'); });

Si no le gustan las alertas, sustitúyalas por console.log

$.getJSON("example.json", function(data) {
  console.log(JSON.stringify(data));
})
.done(function() { console.log('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { console.log('getJSON request failed! ' + textStatus); })
.always(function() { console.log('getJSON request ended!'); });
usuario2314737
fuente
¿Cuál es el orden cronológico de hecho, falla, siempre y el código dentro de getJSON?
TheLogicGuy
nota: console.log no está implementado en navegadores antiguos como IE7. ¡En caso de que lo uses!
MadMad666
12

Sé que ha pasado un tiempo desde que alguien respondió aquí y el cartel probablemente ya recibió su respuesta, ya sea de aquí o de otro lugar. Sin embargo, creo que esta publicación ayudará a cualquiera que busque una forma de realizar un seguimiento de los errores y los tiempos de espera al hacer solicitudes getJSON. Por lo tanto debajo de mi respuesta a la pregunta

La estructura getJSON es la siguiente (que se encuentra en http://api.jqueri.com ):

$(selector).getJSON(url,data,success(data,status,xhr))

la mayoría de las personas implementan eso usando

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

donde usan la var url para proporcionar un enlace a los datos JSON, los datos terminan como un lugar para agregar las "?callback=?"otras variables que deben enviarse para obtener los datos JSON correctos y la función de éxito como función para procesar los datos .

Sin embargo, puede agregar el estado y las variables xhr en su función de éxito. La variable de estado contiene una de las siguientes cadenas: "éxito", "no modificado", "error", "tiempo de espera" o "parsererror", y la variable xhr contiene el objeto XMLHttpRequest devuelto (que se encuentra en 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 esta manera, es fácil realizar un seguimiento de los tiempos de espera y los errores sin tener que implementar un rastreador de tiempo de espera personalizado que se inicia una vez que se realiza una solicitud.

Espero que esto ayude a alguien que todavía está buscando una respuesta a esta pregunta.

Tom Groentjes
fuente
2
Esto no funciona La devolución de llamada de "éxito", como su nombre lo indica, solo se llama al éxito. (Así que no estoy seguro de para qué sirve el parámetro "estado" ...)
jwelsh
4

$.getJSON("example.json", function() {
  alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })

Está arreglado en jQuery 2.x; En jQuery 1.x nunca recibirá una devolución de llamada de error

Pavlo O.
fuente
1

Me enfrenté a este mismo problema, pero en lugar de crear devoluciones de llamada para una solicitud fallida, simplemente devolví un error con el objeto de datos json.

Si es posible, esta parece ser la solución más fácil. Aquí hay una muestra del código Python que utilicé. (Usando Flask, jsonify f de Flask y SQLAlchemy)

try:
    snip = Snip.query.filter_by(user_id=current_user.get_id(), id=snip_id).first()
    db.session.delete(snip)
    db.session.commit()
    return jsonify(success=True)
except Exception, e:
    logging.debug(e)
    return jsonify(error="Sorry, we couldn't delete that clip.")

Luego puede verificar Javascript de esta manera;

$.getJSON('/ajax/deleteSnip/' + data_id,
    function(data){
    console.log(data);
    if (data.success === true) {
       console.log("successfully deleted snip");
       $('.snippet[data-id="' + data_id + '"]').slideUp();
    }
    else {
       //only shows if the data object was returned
    }
});
Nick Woodhams
fuente
Esto está bien para los errores que ocurren dentro del servidor, pero no se captura cuando la llamada no puede llegar al servidor o si se produce un error antes de que llegue al código del servidor, como si un usuario MVC ya no está autenticado.
Lee Oades
1

Por qué no

getJSON('get.php',{cmd:"1", typeID:$('#typesSelect')},function(data) {
    // ...
});

function getJSON(url,params,callback) {
    return $.getJSON(url,params,callback)
        .fail(function(jqXMLHttpRequest,textStatus,errorThrown) {
            console.dir(jqXMLHttpRequest);
            alert('Ajax data request failed: "'+textStatus+':'+errorThrown+'" - see javascript console for details.');
        })
}

??

Para obtener detalles sobre el .fail()método utilizado (jQuery 1.5+), consulte http://api.jquery.com/jQuery.ajax/#jqXHR

Como la jqXHRfunción devuelve el, un encadenamiento como

$.when(getJSON(...)).then(function() { ... });

es posible.

phil294
fuente
0

En algunos casos, puede encontrarse con un problema de sincronización con este método. Escribí la llamada de devolución de llamada dentro de unsetTimeout función, y funcionó sincrónicamente bien =)

P.EJ:

function obterJson(callback) {


    jqxhr = $.getJSON(window.location.href + "js/data.json", function(data) {

    setTimeout(function(){
        callback(data);
    },0);
}
Alex Alonso
fuente