2011-06-07 19 views
38

Mediante el uso de la función jQuery Ajax, que puede hacer algo como:Cómo desencadenar la devolución de llamada de error jquery.ajax() en función de la respuesta del servidor, no HTTP 500?

$.ajax({ 

    url: url, 
    type: 'GET', 
    async: true, 
    dataType: 'json', 
    data: data, 

success: function(data) { 

    //Handle server response here 

    }, 

error: function(xhr, status, error){ 

    //Handle failure here 

} 

}); 

Tengo dos preguntas que hacer sobre la base de código anterior:

  1. ¿Cuándo el jquery.ajax() error devolución de llamada será ¿¿llamado??

  2. ¿Qué pasa si el servidor me responde un objeto json con el mensaje de cadena "Hay un error". Lo que significa que la solicitud aún se envía correctamente, pero recibí la respuesta del servidor {message: "There is an error"}.

Creo que no importa qué cadena de valor del servidor se responsed, si el cliente tiene la respuesta del servidor, se activará la jquery.ajax()success de devolución de llamada de todos modos.

me gustaría preguntar si servidor devuelve específicamente para mí un objeto JSON con valor de cadena como {message: 'There is an error'}, podría servidor de hacer algo para que esta respuesta podría ser manejada de jquery.ajax()error de devolución de llamada en lugar de success devolución de llamada ?

Respuesta

27

La devolución de llamada por error se ejecutará cuando la respuesta del servidor no sea la esperada. Así por ejemplo, en estas situaciones es:

  • HTTP 404/500 o cualquier otro mensaje de error HTTP se ha recibido
  • datos de tipo incorrecto fue recibido JSON (es decir, usted ha esperado, que ha recibido algo más).

En su caso, los datos son correctos (es un mensaje JSON). Si desea activar manualmente la devolución de llamada de error en función del valor de los datos recibidos, puede hacerlo de manera bastante simple. Simplemente cambie la devolución de llamada anónima por error a la función nombrada.

function handleError(xhr, status, error){ 

    //Handle failure here 

} 

$.ajax({ 

    url: url, 
    type: 'GET', 
    async: true, 
    dataType: 'json', 
    data: data, 

success: function(data) { 
    if (whatever) { 
     handleError(xhr, status, ''); // manually trigger callback 
    } 
    //Handle server response here 

    }, 

error: handleError 
}); 
+2

¿Por qué definir handleError en una ubicación separada? ¿Por qué no definirlo en línea así: 'error: handleError = function (xhr, status) {// manejar la respuesta del servidor aquí}' – dallin

+1

@dallin porque le permite no duplicar el código. El servidor puede responder con el código 200 que desencadena la devolución de llamada "exitosa". O bien, un código incorrecto como 400, 404 o 500 activaría la devolución de llamada de "error". En ambos casos, es probable que desee manejar el error de forma centralizada. –

+1

@MichaelButler Creo que podría malinterpretar lo que estaba sugiriendo. Creo que puede definir una función llamada handleError directamente en la propiedad de error (error: handleError = function (xhr, status)). Esto le permite invocar manualmente la función y manejar el error en una ubicación centralizada. Mantendría el manejo del error directamente en la llamada ajax, centralizando las cosas aún más. Aquí hay un jsfiddle con un ejemplo simplificado: http://jsfiddle.net/dhq01bLv/ – dallin

3

La devolución de llamada de error es para cuando el viaje de ida y vuelta de Ajax no se pudo completar con éxito, no algo basado en la lógica de su servidor. Sería su responsabilidad comprobar lo que considera que es una respuesta exitosa dentro de la devolución de llamada exitosa. es decir, agregue un único condicional IF que compruebe si el mensaje = "Hubo un error". e incluya su lógica de error allí, de lo contrario haga la lógica de éxito.

Un enfoque para hacer lo que usted pide sería que el servidor devuelva un encabezado 404 cuando hay un error, entonces sería manejado por la devolución de llamada por error. El problema con este enfoque es que se estaría ocultando si hay errores reales, y no podría pasar datos adicionales con él.

+0

veo, así que no hay manera de accionar de respuesta de error en base a qué servidor responsed , ¿derecho? – Leem

+0

@Leem Es solo una función ... Me está costando averiguar por qué quieres que eso suceda en lugar de buscar el error en los datos de respuesta. Aunque agregué un método de pirateo. – Fosco

+0

Me gustaría ver si existe la posibilidad de desencadenar un error de devolución de llamada en mi caso, espero que esta motivación no te de más dificultades. La respuesta de RaYell me aclara. Gracias también. – Leem

2

Lo más sencillo sería reestructurar este modo:

function handleAjaxError function(xhr, status, error) { 
    //Handle failure here 
} 

$.ajax({ 
    url: url, 
    type: 'GET', 
    async: true, 
    dataType: 'json', 
    data: data, 

    success: function(data) { 

    //Handle server response here 
    if (data.message == 'There is an error') 
    { 
     handleAjaxError(); 
     return; 
    } 

    //... all is good.... 

    }, 
    error: handleAjaxError 
}); 
21

Suponemos que el servidor está enviando JSON, y en caso de una solicitud exitosa nos pondremos algo como esto:

{ 
    success: true, 
    data: { 
     name: 'Foo' 
    } 
} 

...y en caso de fallo:

{ 
    success: false, 
    error: 'Something bad happened.' 
} 

entonces simplemente filtrar la respuesta con un $.Deferred:

$.get('http://localhost/api').then(function(res) { 
    var filter = $.Deferred(); 

    if (res.success) { 
     filter.resolve(res.data); 
    } else { 
     filter.reject(res.error); 
    } 

    return filter.promise(); 
}).done(function(data) { 
    console.log('Name:', data.name); // Outputs: Foo 
}).fail(function(error) { 
    console.log('Error:', error); // Outputs: Something bad happened. 
}) 
+0

Fantástico. Creo que esto es lo que el OP realmente pidió. – Jeroen

0

Una manera fácil de hacer esto es usar el jQuery función siempre() para su devolución de llamada y luego, si Si desea crear un error manualmente, ¡solo aproveche Duck Typing!

Por ejemplo:

$.get(url, {"data": data}).always(function(result) 
{ 
    if (typeof result.status !== "undefined" && result.status !== 200) // Status code 200 represents Success/OK 
    { 
     //handle error 
     error = "Your error was " + result.status + " " + result.statusText; 
    } 
    else 
    { 
     //success 
    } 
}); 

La sección de error siempre se ejecutará si había un error de encabezamiento natural, como un 404 no encontrado. Si desea volver manualmente un error, sólo puede emular el objeto XHR normalmente pasado con un error (por ejemplo en PHP):

public function ServerSideAjaxResponse($data) 
{ 
    if (!$data) 
    { 
     $response["status"] = 1001; //Make up your own error codes! Yippee! Fun! 
     $response["statusText"] = "Error! You forgot to send the data!"; 
     echo json_encode($return); 
     return; 
    } 
} 
Cuestiones relacionadas