Использовать json-ответ из кеша браузера вместо перезагрузки при использовании кнопки «Назад назад» [дубликат]

Хорошая цель с самого начала - основанная на характере вашего сайта, я нашел много ресурсов по этому поводу в Googling - вы, конечно, не первый в этом разбираетесь.

Предполагается, что у мистического PHP6 все это выпрямилось, правда?

Вы можете в значительной степени установить utf-8 в качестве глобальной кодировки по умолчанию для mysql на уровне сервера, и она по умолчанию будет правильно соответствовать более гранулированных уровней.

74
задан cammil 14 June 2013 в 09:30
поделиться

5 ответов

cache:true работает только с запросами GET и HEAD.

Вы можете свернуть свое собственное решение, как вы сказали, что-то в этом направлении:

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

Работа fiddle here

EDIT: поскольку этот пост становится популярным, вот еще лучший ответ для тех, кто хочет управлять тайм-аутом тайм-аута, и вам также не нужно беспокоиться о всех беспорядках в $. ajax () , поскольку я использую $. ajaxPrefilter () . Теперь достаточно установить {cache: true}, чтобы правильно обработать кеш:

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

Вот работающая, но ошибочная реализация, работающая с отложенными:

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 HERE Некоторые проблемы, наш идентификатор кэша зависит от представления объекта json2 lib JSON.

Используйте консольное представление (F12) или FireBug для просмотра некоторых журналов, сгенерированных кешем.

122
ответ дан TecHunter 4 September 2018 в 09:24
поделиться

Я искал кеширование для моего приложения для хранения телефонных разговоров, и я нашел ответ @TecHunter, который замечательный, но сделанный с помощью localCache.

Я нашел и узнал, что localStorage - это еще одна альтернатива кешировать данные, возвращаемые вызовом ajax. Итак, я создал одно демо с помощью localStorage, которое поможет другим, кто захочет использовать localStorage вместо localCache для кеширования.

Ajax Call:

$.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!");
    }
});

Чтобы сохранить данные в localStorage:

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

    options.cache = false; //remove jQuery cache as we have our own localStorage
    options.beforeSend = function () {
        if (localStorage.getItem(url)) {
            success(localStorage.getItem(url));
            return false;
        }
        return true;
    };
    options.success = function (data, textStatus) {
        var responseData = JSON.stringify(data.responseJSON);
        localStorage.setItem(url, responseData);
        if ($.isFunction(success)) success(responseJSON); //call back to original ajax call
    };
}
});

Если вы хотите удалить localStorage, используйте следующую инструкцию везде, где хотите:

localStorage.removeItem("Info");

Надеюсь, что это поможет другим!

9
ответ дан Mayank Modi 4 September 2018 в 09:24
поделиться

Старый вопрос, но мое решение немного другое.

Я писал одностраничное веб-приложение, которое постоянно вызывало вызовы ajax, вызванные пользователем, и чтобы сделать его еще более трудным, требуются библиотеки который использовал методы, отличные от jquery (например, dojo, native xhr и т. д.). Я написал плагин для одной из моих собственных библиотек для кэширования ajax-запросов как можно более эффективным способом, который будет работать во всех основных браузерах, независимо от того, какие библиотеки использовались для вызова ajax.

В решении используется jSQL (написанный мной - постоянная реализация SQL на стороне клиента, написанная в javascript, которая использует методы индексированияddddd и другие методы хранения) и в комплекте с другой библиотекой под названием XHRCreep (написанный мной), который является полной перезаписью собственного объекта XHR.

Чтобы реализовать все, что вам нужно сделать, это включить плагин на вашей странице, который находится здесь .

Существует два варианта:

jSQL.xhrCache.max_time = 60;

Установите максимальный возраст в минутах. все кэшированные ответы, которые старше этого, запрашиваются повторно. Значение по умолчанию - 1 час.

jSQL.xhrCache.logging = true;

Если установлено значение true, для отладки отображаются консольные вызовы XHR.

Вы можете очистить кеш на любой заданной странице с помощью

jSQL.tables = {}; jSQL.persist();
1
ответ дан Occam's Razor 4 September 2018 в 09:24
поделиться

Все современные браузеры предоставляют вам apis для хранения. Вы можете использовать их (localStorage или sessionStorage) для сохранения ваших данных.

Все, что вам нужно сделать, это после получения ответа хранить его в хранилище браузера. Затем в следующий раз, когда вы найдете тот же вызов, выполните поиск, если ответ уже сохранен. Если да, верните ответ оттуда; если не сделать новый вызов.

Плагин Smartjax также выполняет похожие действия; но поскольку ваше требование просто сохраняет ответ на вызов, вы можете написать свой код внутри вашей функции jQuery ajax success, чтобы сохранить ответ. И перед вызовом просто проверьте, сохранен ли ответ.

6
ответ дан Paul Shan 4 September 2018 в 09:24
поделиться

Если я понял ваш вопрос, вот решение:

    $.ajaxSetup({ cache: true});

и для конкретных вызовов

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

Если вы хотите наоборот (кэш для конкретных вызовов), вы можете установите false в начале и true для конкретных вызовов.

5
ответ дан Rebse 4 September 2018 в 09:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: