Остановить кеширование ответа jQuery .load


244

У меня есть следующий код, делающий запрос GET на URL:

$('#searchButton').click(function() {
    $('#inquiry').load('/portal/?f=searchBilling&pid=' + $('#query').val());            
});

Но возвращаемый результат не всегда отражается. Например, я внес изменение в ответ, которое выдает след стека, но след стека не появился, когда я нажал на кнопку поиска. Я посмотрел на базовый код PHP, который контролирует ответ ajax, и он содержал правильный код, и посещение страницы напрямую показало правильный результат, но результат, возвращаемый .load, был старым.

Если я закрою браузер и снова открою его, он будет работать один раз, а затем начнет возвращать устаревшую информацию. Могу ли я контролировать это с помощью jQuery или мне нужно иметь выходные заголовки PHP-скрипта для управления кэшированием?

Ответы:


419

Вы должны использовать более сложную функцию, например, $.ajax()если вы хотите контролировать кэширование для каждого запроса. Или, если вы просто хотите отключить его для всего, поместите это в верхнюю часть вашего скрипта:

$.ajaxSetup ({
    // Disable caching of AJAX responses
    cache: false
});

2
Спасибо! Это даже находится в документации jQuery? Ааа ... нашел это. Вид ягодный. Большую часть дня это било по ногам ... Еще раз спасибо!
— bytebender

35
Весь этот кеш: ложный делает добавление числа (я полагаю, это отметка времени) в конце URL при выполнении запроса. Другое место для обработки настроек кеша - от сервера или веб-приложения, устанавливая различные заголовки HTTP-ответов, такие как Expires, Pragma и т. Д.
— Брайан Ребейн

1
Эта часть информации мне очень помогла - она ​​помогла мне найти действительно неприятную ошибку
— Luke101

Любить это! Теперь мне не нужно использовать слишком подробные вызовы .ajax и я могу использовать ярлыки!
— Гатстер

1
Замечательно - я нашел эту функцию, но не знал, что она будет работать на чем-то столь же простом, как загрузка текстового документа в div с использованием .load
— Дан

107

Вот пример того, как управлять кэшированием для каждого запроса

$.ajax({
    url: "/YourController",
    cache: false,
    dataType: "html",
    success: function(data) {
        $("#content").html(data);
    }
});

7
Мне нравится этот способ гораздо лучше, чем просто отключить кеширование.
— Пол Томблин

Мне также нравится это, чтобы не отключить все кэширование. Кроме того, посмотрите на этот пост также [ссылка] stackoverflow.com/questions/4245231/… для фильтрации.
— Дэн Дойон

@ Маршалл, код здесь, который вы не упомянули, POST или Get type ...... так что по умолчанию для jquery?
— Томас

по умолчанию используется метод GET
— Rich T.

35

Одним из способов является добавление уникального номера в конец URL:

$('#inquiry').load('/portal/?f=searchBilling&pid=' + $('#query').val()+'&uid='+uniqueId());

Где вы пишете uniqueId (), чтобы каждый раз вызывать что-то новое.


1
Еще проще, просто используйте (+new Date)(или, new Date().getTime()если вы сторонник). Посмотрите, как вы получаете метку времени в JavaScript?
— Третий

Задайте новый вопрос и свяжите его здесь. Если вы все сделали правильно, вы создаете совершенно новые URL, поэтому они не могут быть кэшированы браузером.
— Лу Франко

использовал это, чтобы решить не связанную проблему. работает угощение
— Алекс

9

Другой способ поместить строку ниже только тогда, когда требуется получить данные с сервера, добавьте строку ниже вместе с вашим URL-адресом ajax.

? _ = '+ Math.round (Math.random () * 10000)


6
/**
 * Use this function as jQuery "load" to disable request caching in IE
 * Example: $('selector').loadWithoutCache('url', function(){ //success function callback... });
 **/
$.fn.loadWithoutCache = function (){
 var elem = $(this);
 var func = arguments[1];
 $.ajax({
     url: arguments[0],
     cache: false,
     dataType: "html",
     success: function(data, textStatus, XMLHttpRequest) {
   elem.html(data);
   if(func != undefined){
    func(data, textStatus, XMLHttpRequest);
   }
     }
 });
 return elem;
}

Это почти сработало для меня. За исключением того, что функция обратного вызова имеет неправильное значение "this". Я изменил вызов func () на следующее, чтобы исправить это: func.call(elem, data, textStatus, XMLHttpRequest);
— GeekyMonkey

5

Саша хорошая идея, я использую микс.

Я создаю функцию

LoadWithoutCache: function (url, source) {
    $.ajax({
        url: url,
        cache: false,
        dataType: "html",
        success: function (data) {
            $("#" + source).html(data);
            return false;
        }
    });
}

И вызвать для различных частей моей страницы, например, на init:

Init: function (actionUrl1, actionUrl2, actionUrl3) {

var ExampleJS = {

Init: function (actionUrl1, actionUrl2, actionUrl3)           ExampleJS.LoadWithoutCache(actionUrl1, "div1");

ExampleJS.LoadWithoutCache (actionUrl2, "div2"); ExampleJS.LoadWithoutCache (actionUrl3, "div3"); }},


4

Это особенно раздражает в IE. По сути, вы должны отправлять HTTP-заголовки «без кеша» обратно с вашим ответом с сервера.


3

Для PHP добавьте эту строку в ваш скрипт, который предоставляет нужную вам информацию:

header("cache-control: no-cache");

или добавьте уникальную переменную в строку запроса:

"/portal/?f=searchBilling&x=" + (new Date()).getTime()

Опция cache: false в функции $ .ajax автоматически добавляет уникальную переменную в строку запроса, как ваше второе предложение.
— Брайан Ребейн

2

НЕ используйте метку времени для создания уникального URL-адреса, поскольку каждая посещаемая страница кэшируется в DOM с помощью jquery mobile, и вы скоро столкнетесь с проблемой нехватки памяти на мобильных устройствах.

$jqm(document).bind('pagebeforeload', function(event, data) {
    var url = data.url;
    var savePageInDOM = true;

    if (url.toLowerCase().indexOf("vacancies") >= 0) {
        savePageInDOM = false;
    }

    $jqm.mobile.cache =  savePageInDOM;
})

Этот код активируется перед загрузкой страницы, вы можете использовать url.indexOf (), чтобы определить, является ли URL-адрес тем, который вы хотите кэшировать, или нет, и соответственно установить параметр кэширования.

Не используйте window.location = ""; чтобы изменить URL, в противном случае вы перейдете к адресу, а pagebeforeload не сработает. Чтобы обойти эту проблему, просто используйте window.location.hash = "";


1
что такое $ jqm? $ jqm = $? $ .mobile.cache не определено
— Luciuz

2

Если вы хотите использовать метод Jquery .load (), добавьте в URL что-то уникальное, например временную метку JavaScript. msgstr "+ новая дата (). getTime ()". Обратите внимание, я должен был добавить «& time =», чтобы он не изменил вашу переменную pid.

$('#searchButton').click(function() {
$('#inquiry').load('/portal/?f=searchBilling&pid=' + $('#query').val()+'&time='+new Date().getTime());            
});

1

Вы можете заменить функцию загрузки jquery версией с кэшем, установленным в false.

(function($) {
  var _load = jQuery.fn.load;
  $.fn.load = function(url, params, callback) {
  if ( typeof url !== "string" && _load ) {
        return _load.apply( this, arguments );
  }
    var selector, type, response,
      self = this,
      off = url.indexOf(" ");

    if (off > -1) {
      selector = stripAndCollapse(url.slice(off));
      url = url.slice(0, off);
    }

    // If it's a function
    if (jQuery.isFunction(params)) {

      // We assume that it's the callback
      callback = params;
      params = undefined;

      // Otherwise, build a param string
    } else if (params && typeof params === "object") {
      type = "POST";
    }

    // If we have elements to modify, make the request
    if (self.length > 0) {
      jQuery.ajax({
        url: url,

        // If "type" variable is undefined, then "GET" method will be used.
        // Make value of this field explicit since
        // user can override it through ajaxSetup method
        type: type || "GET",
        dataType: "html",
        cache: false,
        data: params
      }).done(function(responseText) {

        // Save response for use in complete callback
        response = arguments;

        self.html(selector ?

          // If a selector was specified, locate the right elements in a dummy div
          // Exclude scripts to avoid IE 'Permission Denied' errors
          jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) :

          // Otherwise use the full result
          responseText);

        // If the request succeeds, this function gets "data", "status", "jqXHR"
        // but they are ignored because response was set above.
        // If it fails, this function gets "jqXHR", "status", "error"
      }).always(callback && function(jqXHR, status) {
        self.each(function() {
          callback.apply(this, response || [jqXHR.responseText, status, jqXHR]);
        });
      });
    }

    return this;
  }
})(jQuery);

Поместите это где-нибудь глобально, где он будет работать после загрузки jquery, и вы должны быть готовы. Ваш существующий код загрузки больше не будет кэшироваться.


0

Попробуй это:

$("#Search_Result").load("AJAX-Search.aspx?q=" + $("#q").val() + "&rnd=" + String((new Date()).getTime()).replace(/\D/gi, ''));

Он отлично работает, когда я его использовал.


0

Я заметил, что если некоторые серверы (например, Apache2) не настроены специально для разрешения или запрета какого-либо «кэширования», то сервер по умолчанию может отправлять «кэшированный» ответ, даже если для заголовков HTTP установлено «no-cache». Поэтому убедитесь, что ваш сервер ничего не "кэширует", прежде чем отправит ответ:

В случае Apache2 вы должны

1) отредактируйте файл "disk_cache.conf" - для отключения кеша добавьте директиву "CacheDisable / local_files"

2) загрузить модули mod_cache (в Ubuntu "sudo a2enmod cache" и "sudo a2enmod disk_cache")

3) перезапустите Apache2 (Ubuntu "sudo service apache2 restart");

Это должно сделать хитрость отключения кэша на стороне сервера. Ура! :)


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.