jQuery.getJSON:如何避免在每次刷新时请求 json 文件? (缓存)

Posted

技术标签:

【中文标题】jQuery.getJSON:如何避免在每次刷新时请求 json 文件? (缓存)【英文标题】:jQuery.getJSON: how to avoid requesting the json-file on every refresh? (caching) 【发布时间】:2012-11-30 22:33:09 【问题描述】:

在此示例中,您可以看到生成的 html 列表。每次刷新时,脚本都会请求数据文件 (ajax/test.json) 并再次构建列表。

生成的文件“ajax/test.json”被静态缓存。但是我怎样才能避免在每次刷新时都请求这个文件呢?

// source: jquery.com
$.getJSON('ajax/test.json', function(data) 
    var items = [];

    $.each(data, function(key, val) 
        items.push('<li id="' + key + '">' + val + '</li>');
    );

    $('<ul/>', 
        'class': 'my-new-list',
        html: items.
    ).appendTo('body');
);

不起作用

list_data = $.cookie("list_data");
if (list_data == undefined || list_data == "") 
    $.getJSON('ajax/test.json', function(data) 
        list_data = data;
    );


var items = [];
$.each(data, function(key, val) 
    items.push('<li id="' + key + '">' + val + '</li>');
);

$('<ul/>', 
    'class': 'my-new-list',
    html: items.
).appendTo('body');

提前致谢!

【问题讨论】:

【参考方案1】:

承诺如何?

var list_data = localStorage.getItem("list_data"),
          def = $.Deferred();

if (!list_data) 
    def = $.getJSON('ajax/test.json', function(data) 
        list_data = data;
        localStorage.setItem("list_data", JSON.stringify(list_data));
    );
else
    list_data = JSON.parse(list_data);
    def.resolve();


def.done(function() 
    var items = [];
    $.each(list_data, function(key, val) 
        items.push( $('<li />', id: key, text: val) );
    );

    $('<ul/>', 'class': 'my-new-list').html(items).appendTo('body');
);
​

我也只使用本地存储,如果要支持 IE7 或更低版本,请使用 MDN 上提供的 shim!

【讨论】:

哇,太棒了——一切正常!非常感谢!现在我只害怕不支持 HTML5 的旧浏览器。我会检查你的 MDN 链接。 在 MDN 上有一个 shim,在页面的下方,可以让你保持本地存储语法,如果不支持本地存储,它会自动使用 cookie,我一直使用它作为本地存储比 cookie 好太多了。【参考方案2】:

因为您的代码循环通过data,它不在您的$.each 所在的范围内。而是:

list_data = $.cookie("list_data");

function buildList(data) 
    var items = [];

    $.each(data, function(key, val) 
        items.push('<li id="' + key + '">' + val + '</li>');
    );

    $('<ul/>', 
        'class': 'my-new-list',
        html: items.
    ).appendTo('body');


//if we dont have list data
if (!list_data) 
    //request for the data
    $.getJSON('ajax/test.json', function(data) 
        list_data = data;
        //build list using new data
        buildList(data);
    );
 else 
    //or use existing list data
    buildList(list_data)

【讨论】:

感谢您的回复,但我注意到 cookie 无法保存大量数据。【参考方案3】:

请注意,如果您停留在同一页面上,则不需要 cookie —— 只需将其存储在某个对象中即可:

window.list_data = data;

如果您需要稍后或在页面刷新后检索数据,请使用 cookie。但是你需要序列化它,因为不可能将对象存储在 cookie 中:

// retrieve
list_data = $.cookie("list_data");
if (list_data) 
    // have to de-serialize from string to object
    list_data = JSON.parse(list_data);
 else 
    // doesn't exist in cookie, make AJAX call


// save
$.cookie("list_data", JSON.stringify(data));

【讨论】:

谢谢,但我只是注意到 cookie 太小,无法保存其中的数据量。【参考方案4】:

您也许可以让浏览器正常缓存文件,请参阅jQuery ajax docs:

http://api.jquery.com/jQuery.ajax/

jQuery.ajax( settings )
cache
Boolean
Default: true, false for dataType 'script' and 'jsonp'
If set to false, it will force requested pages not to be cached by the browser. 
Setting cache to false also appends a query string parameter, "_=[TIMESTAMP]", to the URL.

如果我理解正确,getJson 只是一个 ajax 调用的抽象,专门用于 json。您应该尝试将其设置为true,这样可以让浏览器正常缓存。

将其放入 cookie 中也可以,但最大大小为 4kb。我假设你的 json 没有那么大。

【讨论】:

太好了,我之前没有读过关于 jQuery 缓存的文章。我会检查一下 - 谢谢!【参考方案5】:

我自己做了一些研究,现在使用现代浏览器中的 localStorage 或 sessionStorage 对象来存储对象一段时间似乎是可行的。两者都有其局限性。通常 localStorage 和 sessionStorage 对象的限制为 5mb。数据在窗口/选项卡的整个生命周期中都是持久的。今天的浏览器支持还不错 (currently 89%)。

sessionStorage 和 localStorage 共享相同的 API。因此,选择在本地存储数据的位置仅取决于您的用例。

使用示例

if (!sessionStorage.myapp) 
   var xhr = new XMLHttpRequest(),
   results = ; // Results of xhr request

   // ...

   // store your xhr results to sessionStorage.
   // Both sessionStorage and localStorage can only store strings.
   sessionStorage.setItem('myapp', JSON.stringify(results));
 

我也会避免使用 cookie,因为它们的大小限制 (4K),而且因为 cookie 在每次交易后都会传回服务器。

Sitepoint 对于当前现有的 Web 存储 API 来说是一个非常好的资源:@​​987654322@

【讨论】:

以上是关于jQuery.getJSON:如何避免在每次刷新时请求 json 文件? (缓存)的主要内容,如果未能解决你的问题,请参考以下文章

每次我需要进行 React 更改时如何避免重新启动服务器?

需要避免每次构建时浏览器刷新的情况

Firestore + Vue:刷新页面时,如何避免数据显示延迟?

JQuery getJson 成功函数在按钮单击时触发

jQuery $.getJSON() 失败

php 如何避免刷新页面重复插入数据到数据库