2010-03-22 12 views
21

Deseo hacer una solicitud de Ajax con respuesta en JSON. Así que hice esta petición Ajax:Cómo devolver una función en 404 en JSON Solicitud de ajax con jQuery?

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

Este código funciona bien, pero cuando mi url me envía un código HTTP 404, no se utilizan devoluciones de llamada, incluso la devolución de llamada completa. Después de la investigación, es porque mi dataType es 'json', por lo que 404 return es HTML y el análisis JSON falló. Entonces no hay devolución de llamada.

¿Tiene alguna solución para llamar a una función de devolución de llamada cuando se genera un 404?

EDITAR: callback completo no llame es return es 404. Si desea una URL con 404 puede llamar a: http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697 es con esta URL tengo mi problema.

Respuesta

19
$.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'); 
    } 
}) 
+4

no decir: "completa: function (estado, texto) {" –

+0

1 Sí, gracias! –

+1

Lo intento también, pero la devolución de llamada completa tampoco es llamada :( Actualizo mi pregunta con esta solución y más explico – shingara

1

¿Es simplemente porque el dataType está configurado como "json"? Si es así, trate de cambiar a text y evaluar el JSON a sí mismo:

$.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'); 
    } 
}); 
+0

Esto falló incluso si funciona como en la URL http://twitter.com/status/user_timeline/shingara.json?count=3&callback=jsonp1269278524295&_=1269278536697 – shingara

+0

¿Qué pasa si lo prueba sin la 'devolución de llamada = jsonp ...' en el URL? Por ejemplo: http://twitter.com/status/user_timeline/shingara.json?count=3&_=1269278536697 –

9

Con la configuración de jQuery utiliza jsonp para transportar los datos. Esto funciona insertando dinámicamente un elemento de script y configurando el URL al valor especificado. Los datos devueltos por el servidor se evalúan como JavaScript, normalmente llamando a la devolución de llamada proporcionada. Si el servidor devuelve un 404, el contenido obviamente no es JavaScript y nunca se llama a la devolución de llamada. Algunos navegadores son compatibles con los manejadores de errores en la etiqueta del script, que se llaman en estas situaciones. Lamentablemente, IE no admite esto. La mejor forma de detectar un error es confiar en un tiempo de espera.

En su caso debe especificar una opción adicional timeout, que hace que se llame al manejador de errores si la devolución de llamada no se llamó a tiempo (lo que sería el caso para una respuesta 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') 
    } 
}); 
+0

La solución de tiempo de espera no resuelta. No llame a nada después de pasar :( – shingara

+0

Lo mismo aquí, el mío solo desencadena el error cada vez que obtiene los datos. –

+0

No estoy seguro de qué está haciendo esta respuesta hasta aquí en -1. –

2

¿No cree que el problema no está en el tipo de datos sino en las solicitudes de dominios cruzados que no puede realizar?

El siguiente código funciona como se espera cuando solicita datos desde el mismo dominio y no lo hace cuando está presentando solicitudes entre dominios:

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} 
    ); 
} 
+0

El problema es que el error nunca llama. No es un problema entre dominios :( – shingara

1

Son conscientes de que a pesar de que el estado HTTP es 404, el el cuerpo real es JSON válido? Por ejemplo, this link tiene la siguiente JSON:

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

Como tal, debe comprobar si sus datos tiene la propiedad error dentro de su función de devolución de llamada normal.

ACTUALIZACIÓN: al parecer, a pesar de que el contenido real de la página es JSON válido, el navegador (he comprobado en Firefox) no está ejecutando la misma, muy probablemente porque es un 404. Debido a que jQuery tiene que añadir un script elemento (debido a la cuestión de dominio cruzado), su envoltorio JSONP nunca se llama, y ​​como consecuencia, tampoco son sus devoluciones de llamada.

Así que, en resumen, no creo que haya una forma de resolver esto sin agregar manualmente ese elemento de script y verificar si su función de devolución de llamada predefinida ha sido llamada posteriormente.

0

Así es como me ocupo de esto. Reviso los datos devueltos para ver si hay errores antes de intentar usarlos. Lo que se muestra a continuación es solo una muestra que puede ampliar para que se ajuste más a sus requisitos. Esto también considera los tiempos de espera de sesión y otros escenarios ...

Mi llamada inicial:

$.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); 
    } 
    }); 

Y las dos funciones auxiliares:

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; 
} 

y

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'); 
} 
1

Sólo se enfrentaron el mismo problema, y ​​vio another question mencionó que jQuery-JSONP (jQuery Plugin) admite catchin g errores 404 o como se describen: "recuperación de errores en caso de fallo de red o respuestas JSON mal formadas"

y funciona perfecto :)

Aquí está mi (simplificado) código de ir a buscar detalles acerca un vídeo de YouTube a través de 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); 
    } 
}); 
+0

Esta es una gran solución para la pregunta real. Es una pena que la biblioteca parezca haber dejado de desarrollarse. ¿Existe alguna solución similar para las versiones modernas de jQuery? –

0

siguiente solución está trabajando muy bien para mí :)

$.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'); 
     } 
    } 
}); 
4

Si desea manejar los errores al acceder a la API de Twitter con Javascript y jsonp, debe incluir el parámetro suppress_response_codes en su solicitud. Esto hace que todas las respuestas de la API de Twitter respondan con una respuesta 200 OK e incluyen un error. Luego debe verificar si la respuesta incluye el parámetro error o no.

$.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); 
    } 
    } 
}); 
3

Uso del statusCode -Opción

$.ajax({ 
    url: 'http://my_url', 
    dataType: "json", 
    statusCode: { 
     404:function(){ 
      alert("I could not find the informations you requested."); 
     } 
    } 
    success: function(data){ 
     alert('success'); 
    }, 
    error: function(data){ 
     alert('error'); 
    }, 
    complete: function(data) { 
     alert('complete') 
    }}) 
Cuestiones relacionadas