【问题标题】:What are possible techniques to cache an Ajax response in Javascript? [closed]在 Javascript 中缓存 Ajax 响应的可能技术有哪些? [关闭]
【发布时间】:2016-02-16 11:20:03
【问题描述】:

我正在实现一个 Javascript 模块管理器,它通过 XHR 对象加载 javascript 文件。这种方法的问题是资源缓存:

  • 首先,XHR 依赖于内置的浏览器缓存机制,这没问题,但它的行为取决于浏览器的实现。
  • 还有一个localStorage 和一个basket.js 使用localStorage 来缓存下载的脚本,问题在于存储空间有限,通常为5-10MB。此外,localStorage 是许多脚本共享的地方,这些脚本也使用它来存储数据。
  • 还有ServiceWorker API 的Cache 接口,但它仅在ServiceWorker 运行时可用,因此它可能符合我的需求。

有谁知道他在他的项目中使用的一些智能的旧的或新的 javascript 缓存技术,或者可能听说过?

注意:请不要建议使用作为XHR 接口的jQuery .ajax,或任何其他实现内置Javascript 功能接口的库。

编辑:有一些有价值的建议:

  • 使用名为 localForage 的库。该库代表了 IndexedDB、WebSQL 和 localStorage 的统一 API,具体使用哪个取决于浏览器。
  • 使用 IndexedDB,它是真正强大的存储,没有明显的空间限制。唯一需要担心的是,只有现代浏览器才能实现 IndexedDB。

【问题讨论】:

  • 在页面刷新后持久化这个缓存有什么具体要求吗?您需要使用本地存储吗?
  • 你想具体完成什么?你想保存什么?
  • 你检查过这个问题了吗 -> stackoverflow.com/questions/17104265/… ?
  • 您想要一个用 Vanilla Javascript 编写且不依赖本地或会话存储的解决方案,对吧?
  • XHR 没有内置缓存机制。 “取决于浏览器实现”是什么意思?浏览器通常会缓存它可以缓存的每个GET 响应。您可以查看 IndexedDB。

标签: javascript ajax caching browser-cache cache-control


【解决方案1】:

这是特定于 JQUERY....

您可以将 ajax 设置为缓存。

    $.ajaxSetup({ cache: true});

如果对于特定调用,您不想做出缓存响应,则调用

 $.ajax({
        url: ...,
        type: "GET",
        cache: false,           
        ...
    });

如果你想要相反(特定调用的缓存),你可以在开头设置 false 并为特定调用设置 true

如果你想存储ajax响应的结果,你可以使用Local Storage。所有现代浏览器都为您提供存储 API。您可以使用它们(localStorage 或 sessionStorage)来保存您的数据。

您所要做的就是在收到响应后将其存储到浏览器存储中。然后下次找到相同的呼叫时,搜索是否已保存响应。如果是,则从那里返回响应;如果不打新电话。

Smartjax plugin 也做类似的事情;但由于您的要求只是保存调用响应,您可以在 jQuery ajax 成功函数中编写代码来保存响应。在拨打电话之前,只需检查响应是否已保存。

【讨论】:

  • 这是 jQuery 特有的。您能否扩展您的答案以包含针对纯 XMLHttpRequests 的答案?
  • jQuery .ajax 只是原生 XHR 对象的一个​​接口,所以对我来说没有帮助
【解决方案2】:

由于 indexeddb 是一种用于在客户端存储数据的方法,因此允许索引数据库查询。

这是支持的浏览器 http://caniuse.com/#feat=indexeddb

这是唯一的问题

Firefox (prior to version 37) and Safari do not support IndexedDB inside web workers.
Not supported in Chrome for iOS or other iOS WebViews.

Chrome 36 and below did not support Blob objects as indexedDB values.

Here is another similar polyfill you can try,但根据我(尽管有限)的经验,这两个 polyfill 都是错误的/不完整的。他们在 GitHub 上也有许多未解决的问题,人们报告问题。当我测试其中一个时(我忘了是哪一个),它比原生 IndexedDB 慢得多。

也许可以创建一个像样的 polyfill,但目前的 polyfill 似乎无法胜任。

我应该使用已弃用的 WebSQL 吗?

WebSQL 的问题在于它永远不会在 IE 或 Firefox 中得到支持。如果您只针对移动浏览器,您可能会摆脱 WebSQL,至少在 Firefox OS 或 Windows Phone 抢占重要市场份额之前。

是否有计划在未来为所有不支持的浏览器支持 IndexedDB?

让我们说清楚。你问的是苹果,因为其他人都在他们最新的浏览器中支持 IndexedDB(iOS Chrome 使用苹果的渲染引擎,因为苹果不会让他们做任何其他事情)。

Apple 不仅不支持 IndexedDB,而且他们也没有公开谈论它(据我所知......而且我已经进行了大量搜索)。这看起来很奇怪。因此,据我所知,没有人知道 Apple 是否计划支持 IndexedDB。我心中的阴谋论者认为他们可能是在试图破坏 HTML5 应用程序以迫使人们编写原生应用程序,但这纯粹是猜测。

总的来说,这让我们的开发人员处于非常糟糕的境地。没有好的跨平台解决方案。我建议您向 Apple 投诉。这就是我所做的,我已经询问了想要在 iOS 上使用我的基于 IndexedDB 的应用程序的用户也这样做。仍然没有来自 Apple 的消息。

更新 - 如 WWDC 2014 所述,iOS 8 现在支持 Indexeddb - 但不幸的是 it's broken pretty badly

还要考虑 子资源 完整性 -

子资源完整性使浏览器能够验证文件是否在没有意外操作的情况下交付。

没有知识问题?到目前为止?

我建议你可以一起去

如果移动设备是您的主要目标,则基于

子资源的解决方案

indexeddb 如果移动设备不是您的主要目标并使用公开可用的移动设备实现

如果以上所有内容对你来说都太复杂了,那么

var localCache = {
    data: {},
    remove: function (url) {
        delete localCache.data[url];
    },
    //a cached version exists
    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); //log only!
        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);
    },
    timeout: 600, //in seconds
};

$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
    if (options.cache) {
        var complete = originalOptions.complete || $.noop,
            url = originalOptions.url;
        //remove jQuery cache as you have your 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 = 'your url goes here';
    $('#ajaxButton').click(function (e) {
        $.ajax({
            url: url,
            data: {
                test: 'value'
            },
                cache: true,
                complete: doSomething
            });
        });
    });
    //ToDo after ajax call finishes, or cached version retrived
    function doSomething(data) {
        console.log(data);
    }

【讨论】:

  • 有关此答案的更多详细信息,请访问我的博客 - maograciag.wordpress.com/2015/11/24/…
  • 我确实记得使用来自其他地方的多个答案来构建我的 - 据我所知,在这里提供链接是不够的,所以我决定在我的答案中收集不同的方法
  • 当然,但是当你从其他来源复制粘贴代码时要提及:)
  • 这个答案涉及很多来源,而且已经太久了。感谢您提及其中之一
【解决方案3】:

另一个具体的 JQUERY 答案?

不确定它是否能回答您的问题,但这可能会有所帮助。它正在缓存具有超时的 ajax 调用。

在预过滤中,列出您要为缓存添加的各种 PHP ajax 调用。 在本例中,缓存启用,超时时间为 10 分钟。

/*----------------------------*/
/* set ajax caching variables */
/*----------------------------*/
$.set_Ajax_Cache_filters = function () {
    var localCache = {
        timeout: 600000, // 10 minutes
        data: {}, //@type {{_: number, 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) {
            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);
        }
    };

    /*----------------------*/
    /* set ajax pre filters */
    /*----------------------*/
    $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
        // list of allowed url to cache
        if (url !== '..............file.php') {
            return false;
        }
        if (options.cache) {
            var complete = originalOptions.complete || $.noop,
                    url = originalOptions.url;

            options.cache = false;//remove jQuery cache using proprietary one
            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);
            };
        }
    });
};

【讨论】:

  • 这似乎是 jQuery 特有的?您能否扩展您的答案以包括针对裸 XMLHttpRequests 的答案
  • 您将面临相当多的代码行,并尝试模拟 ajaxPrefilter。我什至不想尝试...
【解决方案4】:

要做到这一点,最好的技术是使用本地缓存、ajaxPrefilter 和 ajax 缓存选项,这三者的组合将为您创建您想要的可靠缓存,您可以轻松控制 这是一个代码示例:

var localCache = {
    data: {},
    remove: function (url) {
        delete localCache.data[url];
    },
    //a cached version exists
    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); //log only!
        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);
    },
    timeout: 600, //in seconds
};

$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
    if (options.cache) {
        var complete = originalOptions.complete || $.noop,
            url = originalOptions.url;
        //remove jQuery cache as you have your 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 = 'your url goes here';
    $('#ajaxButton').click(function (e) {
        $.ajax({
            url: url,
            data: {
                test: 'value'
            },
                cache: true,
                complete: doSomething
            });
        });
    });
    //ToDo after ajax call finishes, or cached version retrived
    function doSomething(data) {
        console.log(data);
    }

享受你的编码

【讨论】:

【解决方案5】:

试试这个可能有用

    var cache = {};
var formatTweets(info) {  
    //formats tweets, does whatever you want with the tweet information
};

//event
$('myForm').addEvent('submit',function() {
    var handle = $('handle').value; //davidwalshblog, for example
    var cacheHandle = handle.toLowerCase();
    if(cache[cacheHandle] != "undefined") {
        formatTweets(cache[cacheHandle]);
    }
    else {
        //gitter
        var myTwitterGitter = new TwitterGitter(handle,{
            count: 10,
            onComplete: function(tweets,user) {
                cache[cacheHandle] = tweets;
                formatTweets(tweets);
            }
        }).retrieve();
    }
});

【讨论】:

    猜你喜欢
    • 2010-10-09
    • 2011-06-16
    • 2023-04-09
    • 2011-04-07
    • 2011-08-16
    • 2023-03-18
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    相关资源
    最近更新 更多