jQuery.getJSON: how to avoid requesting the json-f

2019-03-31 04:15发布

in this example you can see a generated HTML-list. On every refresh the script requests the data-file (ajax/test.json) and builds the list again.

The generated file "ajax/test.json" is cached statically. But how can I avoid requesting this file on every refresh?

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

This doesn't work:

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

Thanks in advance!

5条回答
叛逆
2楼-- · 2019-03-31 04:42

Because your code loops through data which is not in the scope where your $.each is. Instead:

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)
}
查看更多
甜甜的少女心
3楼-- · 2019-03-31 04:58

Note that, if you're staying on the same page, you don't need a cookie -- can just stash it in an object somewhere:

window.list_data = data;

If you need to retrieve the data later, or after the page has been refreshed, then use a cookie. But you need to serialize it, because it's not possible to store an object in a 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));
查看更多
霸刀☆藐视天下
4楼-- · 2019-03-31 05:00

You may be able to have the browser cache the file normally, see 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.

If I understand correctly, getJson is just an abstraction of an ajax call, specifically for json. You should try setting it to true, which would let the browser cache normally.

Putting it in a cookie can work as well, but has a max size of 4kb. I'm assuming your json isn't nearly that large though.

查看更多
SAY GOODBYE
5楼-- · 2019-03-31 05:02

I did some research myself and it seems that it's feasible to utilize localStorage or the sessionStorage object in Modern Browsers nowadays to storage objects for a certain amount of time. Both have it's limits. Typically the localStorage and sessionStorage object have limits of 5mb. The data is persistent throughout the lifetime of the window/tab. Support isn't too bad (currently 89%) of browsers today.

Both sessionStorage and localStorage share the same API. So choosing where to store your data locally just depends on your use case.

Example of usage

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

I would also avoid using cookies because of their size limits (4K) and also because cookies are passed back to the server after each transaction.

Sitepoint is a really good resource for the current existing web storage API: http://www.sitepoint.com/an-overview-of-the-web-storage-api/

查看更多
男人必须洒脱
6楼-- · 2019-03-31 05:05

How 'bout a promise ?

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

I'd also just use local storage, and if IE7 or below is to be supported, use the shim available on MDN!

查看更多
登录 后发表回答