A partir de jQuery 1.5, los métodos ajax ahora manejan correctamente las respuestas 304 no modificadas llamando al controlador de éxito (), según la especificación W3C para XMLHTTPRequest. Esto permite que su aplicación trate la solicitud como exitosa, incluso si el servidor en realidad no devolvió ningún dato (porque ya tiene los últimos datos almacenados en caché).
Para una solicitud GET normal (no almacenada en caché), se llama al controlador de éxito con los siguientes argumentos:
Para una solicitud GET en caché, se llama al controlador de éxito con los siguientes argumentos:
(al menos, así es como se devuelve en IOS 4.2, para una aplicación web que usa el caché de la aplicación a través de un archivo de manifiesto. Supongo que esto es consistente para el almacenamiento en caché general del navegador en la mayoría de las plataformas/navegadores).
Puede ver que el argumento "datos" solo se completa si la solicitud fue 200 OK; donde jqXHR.responseText siempre se completa con datos, independientemente de si esos datos provienen del servidor (200 OK) o del caché (304 No modificado).
Dado que, en la mayoría de las solicitudes GET, su controlador de éxito querrá hacer algo con los datos que obtuvo sin importar de dónde provengan, parecería tener más sentido que su código de éxito use siempre jqXHR.responseText, en lugar de hacer algo como esto:
if ("notmodified" === status) { // do something with jqXHR.responseText } else { // do something with data }
¿O hay algún caso en el que jqXHR.responseText no se complete en el controlador de éxito, pero el argumento de datos sí ?
Tengo que revisar mi base de código y cambiar todos los controladores de éxito (anteriormente estaba en jQuery 1.4.2, que siempre devolvía datos, incluso desde el caché); así que solo quiero asegurarme de que lo estoy manejando de la manera correcta. (No quiero llegar al final y luego darme cuenta de que debería haberlo hecho de otra manera).
Acabo de detectar la falla obvia en mi pregunta... Supuse que los datos siempre eran texto, por lo que usar jqXHR.responseText en lugar del argumento de datos tenía sentido.
Pero en el caso de que el tipo de datos sea JSON, JSONP, secuencia de comandos, etc., si los datos devueltos en una respuesta 304 no modificada vuelven como indefinidos, primero deberá convertir jqXHR.responseText de una cadena al tipo deseado. , p.ej.
if (data === undefined) { data = $.parseJSON(jqXHR.responseText); }
... y solo querrá hacer esta conversión (potencialmente costosa) cuando realmente la necesite.
Tiene algo de sentido ahora que lo pienso... los datos siempre serán los que regresaron del servidor (lo que en algunos casos podría no estar indefinido para un 304... por ejemplo, el servidor podría devolver algún texto/html adicional) ); lo que le permite al desarrollador la flexibilidad de elegir lo que quiere hacer en el caso de un 304, por ejemplo.
Dependiendo del contexto, puede usar el parámetro de cache
para la solicitud ajax:
$.ajax({ url: ".....", dataType: "json", type: "GET", cache: false, contentType: "application/json", success: function (data, textStatus) { console.log("RECV: " + data); } });
Eso está funcionando para mí.