缓存在JavaScript /浏览器的jQuery Ajax响应 [英] Caching a jquery ajax response in javascript/browser

查看:161
本文介绍了缓存在JavaScript /浏览器的jQuery Ajax响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现的在JavaScript /浏览器中的Ajax响应缓存。

I would like to enable caching of an ajax response in javascript/browser.

在<一个href="http://api.jquery.com/jQuery.ajax/?rdfrom=http://docs.jquery.com/mw/index.php?title=Ajax/jQuery.ajax&redirect=no#options">jquery.ajax文档:

在默认情况下,请求总是发出,但浏览器可以用于   导致其缓存。要禁止使用缓存的结果,集   缓存为false。要使请求,如果该资产报告故障   自从上次请求后没有被修改,设置ifModified为true。

By default, requests are always issued, but the browser may serve results out of its cache. To disallow use of the cached results, set cache to false. To cause the request to report failure if the asset has not been modified since the last request, set ifModified to true.

然而,无论这些地址迫使缓存。

However, neither of these address forcing caching.

激励: 我想把 $。阿贾克斯({...})在我的初始化函数,其中一些要求相同的URL调用。有时候,我需要调用这些初始化函数之一,有时我叫几个。

Motivation: I want to put $.ajax({...}) calls in my initialisation functions, some of which request the same url. Sometimes I need to call one of these initialisation functions, sometimes I call several.

所以,我想请求到服务器,最大限度地减少该特定网址已经被加载。

我会推出自己的解决方案(有一定的难度!),但我想知道是否有这样做的标准方法。

I could roll my own solution (with some difficulty!), but I would like to know if there is a standard way of doing this.

推荐答案

缓存:真正的只能使用GET和HEAD请求

cache:true only works with GET and HEAD request.

您可以推出自己的解决方案为您提供这些方针的东西说:

You could roll your own solution as you said with something along these lines :

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

这里 工作拨弄

Working fiddle here

编辑:由于这个职位成为热门,这里是一个更好的答案,谁想要管理超时缓存,你也不必费心在的 $。阿贾克斯()因为我用 $。阿贾克斯prefilter()。现在,只要设置 {缓存:真} 足以正确处理缓存:

as this post becomes popular, here is an even better answer for those who want to manage timeout cache and you also don't have to bother with all the mess in the $.ajax() as I use $.ajaxPrefilter(). Now just setting {cache: true} is enough to handle the cache correctly :

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) {
        var complete = originalOptions.complete || $.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);
}

这里的小提琴 小心,不工作$ .Deferred

下面是一个工作,但有缺陷的执行工作延期:

Here is a working but flawed implementation working with deferred:

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

小提琴这里 有些问题,我们的高速缓存标识依赖的json2 LIB JSON对象重新presentation。

Fiddle HERE Some issues, our cache ID is dependent of the json2 lib JSON object representation.

使用控制台视图(F12)或萤火查看由高速缓存产生了一些日志。

Use Console view (F12) or FireBug to view some logs generated by the cache.

这篇关于缓存在JavaScript /浏览器的jQuery Ajax响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆