Остановить кеширование ответа 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.