Saltar al contenido

Almacenamiento en caché de una respuesta jquery ajax en javascript / browser

Por fin después de mucho batallar pudimos encontrar el resultado de este inconveniente que algunos de nuestros usuarios de este espacio han presentado. Si deseas compartir algo no dejes de compartir tu comentario.

Solución:

cache:true solo funciona con solicitudes GET y HEAD.

Podrías desarrollar tu propia solución como dijiste con algo como esto:

var localCache = 
    data: ,
    remove: function (url) 
        delete localCache.data[url];
    ,
    exist: function (url) 
        return localCache.data.hasOwnProperty(url) && localCache.data[url] !== null;
    ,
    get: function (url) 
        console.log('Getting in cache for url' + url);
        return localCache.data[url];
    ,
    set: function (url, cachedData, callback) 
        localCache.remove(url);
        localCache.data[url] = cachedData;
        if ($.isFunction(callback)) callback(cachedData);
    
;

$(function () 
    var url = '/echo/jsonp/';
    $('#ajaxButton').click(function (e) 
        $.ajax(
            url: url,
            data: 
                test: 'value'
            ,
            cache: true,
            beforeSend: function () 
                if (localCache.exist(url)) 
                    doSomething(localCache.get(url));
                    return false;
                
                return true;
            ,
            complete: function (jqXHR, textStatus) 
                localCache.set(url, jqXHR, doSomething);
            
        );
    );
);

function doSomething(data) 
    console.log(data);

Trabajando el violín aquí

EDITAR: a medida que esta publicación se vuelve popular, aquí hay una respuesta aún mejor para aquellos que desean administrar el caché de tiempo de espera y tampoco tienen que preocuparse por todo el lío en $ .ajax () ya que yo uso $ .ajaxPrefilter () . Ahora solo estableciendo cache: true es suficiente para manejar la caché correctamente:

var localCache = 
    /**
     * timeout for cache in millis
     * @type number
     */
    timeout: 30000,
    /** 
     * @type _: number, data: 
     **/
    data: ,
    remove: function (url) 
        delete localCache.data[url];
    ,
    exist: function (url) 
        return !!localCache.data[url] && ((new Date().getTime() - localCache.data[url]._) < localCache.timeout);
    ,
    get: function (url) 
        console.log('Getting in cache for url' + url);
        return localCache.data[url].data;
    ,
    set: function (url, cachedData, callback) 
        localCache.remove(url);
        localCache.data[url] = 
            _: new Date().getTime(),
            data: cachedData
        ;
        if ($.isFunction(callback)) callback(cachedData);
    
;

$.ajaxPrefilter(function (options, originalOptions, jqXHR) 
    if (options.cache)  $.noop,
            url = originalOptions.url;
        //remove jQuery cache as we have our own localCache
        options.cache = false;
        options.beforeSend = function () 
            if (localCache.exist(url)) 
                complete(localCache.get(url));
                return false;
            
            return true;
        ;
        options.complete = function (data, textStatus) 
            localCache.set(url, data, complete);
        ;
    
);

$(function () 
    var url = '/echo/jsonp/';
    $('#ajaxButton').click(function (e) 
        $.ajax(
            url: url,
            data: 
                test: 'value'
            ,
            cache: true,
            complete: doSomething
        );
    );
);

function doSomething(data) 
    console.log(data);

Y el violín aquí CUIDADO, no funciona con $ .Deferred

Aquí hay una implementación funcional pero defectuosa que funciona con diferido:

var localCache = 
    /**
     * timeout for cache in millis
     * @type number
     */
    timeout: 30000,
    /** 
     * @type _: number, data: 
     **/
    data: ,
    remove: function (url) 
        delete localCache.data[url];
    ,
    exist: function (url) 
        return !!localCache.data[url] && ((new Date().getTime() - localCache.data[url]._) < localCache.timeout);
    ,
    get: function (url) 
        console.log('Getting in cache for url' + url);
        return localCache.data[url].data;
    ,
    set: function (url, cachedData, callback) 
        localCache.remove(url);
        localCache.data[url] = 
            _: new Date().getTime(),
            data: cachedData
        ;
        if ($.isFunction(callback)) callback(cachedData);
    
;

$.ajaxPrefilter(function (options, originalOptions, jqXHR) 
    if (options.cache) 
        //Here is our identifier for the cache. Maybe have a better, safer ID (it depends on the object string representation here) ?
        // on $.ajax call we could also set an ID in originalOptions
        var id = originalOptions.url+ JSON.stringify(originalOptions.data);
        options.cache = false;
        options.beforeSend = function () 
            if (!localCache.exist(id)) 
                jqXHR.promise().done(function (data, textStatus) 
                    localCache.set(id, data);
                );
            
            return true;
        ;

    
);

$.ajaxTransport("+*", function (options, originalOptions, jqXHR, headers, completeCallback) 

    //same here, careful because options.url has already been through jQuery processing
    var id = originalOptions.url+ JSON.stringify(originalOptions.data);

    options.cache = false;

    if (localCache.exist(id)) 
        return 
            send: function (headers, completeCallback) 
                completeCallback(200, "OK", localCache.get(id));
            ,
            abort: function () 
                /* abort code, nothing needed here I guess... */
            
        ;
    
);

$(function () 
    var url = '/echo/jsonp/';
    $('#ajaxButton').click(function (e) 
        $.ajax(
            url: url,
            data: 
                test: 'value'
            ,
            cache: true
        ).done(function (data, status, jq) 
            console.debug(
                data: data,
                status: status,
                jqXHR: jq
            );
        );
    );
);

Fiddle AQUÍ Algunos problemas, nuestra ID de caché depende de la representación del objeto JSON lib json2.

Use la vista Consola (F12) o FireBug para ver algunos registros generados por la caché.

Estaba buscando almacenamiento en caché para el almacenamiento de mi aplicación phonegap y encontré la respuesta de @TecHunter, que es excelente, pero ya he terminado de usar localCache.

Encontré y llegué a saber que localStorage es otra alternativa para almacenar en caché los datos devueltos por la llamada ajax. Entonces, creé una demostración usando localStorage que ayudará a otros que quieran usar localStorage en lugar de localCache para el almacenamiento en caché.

Llamada Ajax:

$.ajax(
    type: "POST",
    dataType: 'json',
    contentType: "application/json; charset=utf-8",
    url: url,
    data: '"Id":"' + Id + '"',
    cache: true, //It must "true" if you want to cache else "false"
    //async: false,
    success: function (data) 
        var resData = JSON.parse(data);
        var Info = resData.Info;
        if (Info) 
            customerName = Info.FirstName;
        
    ,
    error: function (xhr, textStatus, error) 
        alert("Error Happened!");
    
);

Para almacenar datos en localStorage:

$.ajaxPrefilter(function (options, originalOptions, jqXHR) 
if (options.cache) 
    var success = originalOptions.success 
);

Si desea eliminar localStorage, use la siguiente declaración donde quiera:

localStorage.removeItem("Info");

¡Espero que ayude a otros!

Todos los navegadores modernos le proporcionan apis de almacenamiento. Puede usarlos (localStorage o sessionStorage) para guardar sus datos.

Todo lo que tiene que hacer es después de recibir la respuesta, almacenarla en el almacenamiento del navegador. Luego, la próxima vez que encuentre la misma llamada, busque si la respuesta ya está guardada. Si es así, devuelva la respuesta desde allí; si no, haga una nueva llamada.

El complemento Smartjax también hace cosas similares; pero como su requisito es simplemente guardar la respuesta a la llamada, puede escribir su código dentro de su función de éxito jQuery ajax para guardar la respuesta. Y antes de realizar la llamada, compruebe si la respuesta ya está guardada.

Tienes la posibilidad recomendar esta división si te ayudó.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *