Предотвращение кэширования браузером результата вызова JQuery AJAX

Похоже, если я загружаю динамический контент с помощью $.get(), результат кэшируется в браузере.

Добавление некоторой случайной строки в QueryString, похоже, решает эту проблему (я использую new Date().toString()), но это похоже на взлома.

Есть ли другой способ достичь этого? Или, если уникальная строка является единственным способом достижения этого, любые предложения, кроме new Date()?

Ответ 1

Я использую new Date().getTime(), который избежит коллизий, если у вас не будет несколько запросов в течение одной миллисекунды:

$.get('/getdata?_=' + new Date().getTime(), function(data) {
    console.log(data); 
});

Изменить: Этот ответ несколько лет. Он по-прежнему работает (следовательно, я его не удалял), но есть лучшие/более чистые способы достижения этого сейчас. Я предпочитаю этот метод, но этот ответ также полезен, если вы хотите отключить кеширование для каждого запроса во время жизни страницы.

Ответ 2

Следующее предотвратит кеширование всех будущих запросов AJAX, независимо от того, какой метод jQuery вы используете ($.get, $.ajax и т.д.)

$.ajaxSetup({ cache: false });

Ответ 3

JQuery $.get() будет кэшировать результаты. Вместо

$.get("myurl", myCallback)

вам следует использовать $.ajax, который позволит вам отключить кеширование:

$.ajax({url: "myurl", success: myCallback, cache: false});

Ответ 4

другой способ - не предоставлять заголовки кеша с сервера в коде, который генерирует ответ на вызов ajax:

response.setHeader( "Pragma", "no-cache" );
response.setHeader( "Cache-Control", "no-cache" );
response.setDateHeader( "Expires", 0 );

Ответ 5

Все ответы здесь оставляют след на запрошенном URL, который будет отображаться в журналах доступа сервера.

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

Результат, по крайней мере, для Chrome:

$.ajax({
   url: url, 
   headers: {
     'Cache-Control': 'no-cache, no-store, must-revalidate', 
     'Pragma': 'no-cache', 
     'Expires': '0'
   }
});

Ответ 6

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

Я обычно использую Math.random(), но я не вижу ничего плохого в использовании даты (вы не должны делать запросы AJAX достаточно быстро, чтобы получить одно и то же значение дважды).

Ответ 7

Вы можете использовать короткую нотацию $.now() вместо выполнения (new Date(). getTime()) каждый раз.

Ответ 8

Следуя документации: http://api.jquery.com/jquery.ajax/

вы можете использовать свойство cache с помощью:

$.ajax({
    method: "GET",
    url: "/Home/AddProduct?",
    data: { param1: value1, param2: value2},
    cache: false,
    success: function (result) {
        // TODO
    }
});

Ответ 9

Как насчет использования запроса POST вместо GET...? (Что вам все равно нужно...)

Ответ 10

Реальный вопрос в том, почему вам это нужно, чтобы не кэшироваться. Если он не должен кэшироваться, потому что он все время меняется, сервер должен указать, чтобы не кэшировать ресурс. Если он просто изменяется иногда (поскольку один из ресурсов, от которого он зависит, может измениться), и если код клиента имеет способ узнать об этом, он может добавить фиктивный параметр к URL-адресу, который вычисляется из некоторого хэша или последней измененной даты (что мы делаем в ресурсах Microsoft Ajax script, чтобы их можно было кэшировать навсегда, но новые версии все равно могут обслуживаться по мере их появления). Если клиент не знает об изменениях, правильный путь должен быть для сервера правильно обрабатывать HEAD-запросы и сообщать клиенту, следует ли использовать кешированную версию или нет. Мне кажется, что добавление случайного параметра или сообщение от клиента никогда не кэшируются неправильно, потому что кеширование является свойством ресурса сервера, поэтому его следует решать на стороне сервера. Другой вопрос, чтобы спросить себя, должен ли этот ресурс действительно обслуживаться через ПОЛУЧИТЬ или должен ли он проходить через POST? Это вопрос семантики, но также имеет последствия для безопасности (есть атаки, которые работают, только если сервер разрешает GET). POST не будет кэшироваться.

Ответ 11

Может быть, вам стоит посмотреть на $.ajax() вместо этого (если вы используете jQuery, как это выглядит). Взгляните на: http://docs.jquery.com/Ajax/jQuery.ajax#options и опцию "cache".

Другим подходом было бы посмотреть, как вы кешируете вещи на стороне сервера.

Ответ 12

Конечно, методы "кэширования" будут выполняться, но это не произойдет в первую очередь, если сервер указал клиенту, что ответ не должен быть кэширован. В некоторых случаях полезно кэшировать ответы, иногда нет. Пусть сервер решит правильное время жизни данных. Возможно, вы захотите изменить его позже. Гораздо проще сделать с сервера, чем из разных мест вашего кода пользовательского интерфейса.

Конечно, это не поможет, если у вас нет контроля над сервером.

Ответ 13

Небольшое дополнение к отличным ответам: если вы работаете с решением для резервного копирования без аякса для пользователей без javascript, вам все равно нужно будет получить эти заголовки на стороне сервера. Это не невозможно, хотя я понимаю тех, кто его отказывается;)

Я уверен, что есть еще один вопрос о SO, который даст вам полный набор заголовков, которые подходят. Я не полностью уверен, что ответ miceus охватывает все базы на 100%.

Ответ 14

Для тех из вас, кто использует опцию cache для $.ajaxSetup() на мобильном Safari, кажется, вам, возможно, придется использовать временную метку для POST, так как кэш Safari также кэширует это. Согласно документации на $.ajax() (к которой вы перенаправлены с $.ajaxSetup()):

Установка кеша в false будет работать только с запросами HEAD и GET. Он работает, добавляя "_ = {timestamp}" к параметрам GET. Параметр не нужен для других типов запросов, за исключением IE8, когда POST создается с URL-адресом, который уже был запрошен GET.

Поэтому настройка этого параметра сама по себе не поможет вам в случае, о котором я упоминал выше.

Ответ 15

В основном просто добавьте cache:false; в ajax, где, по вашему мнению, содержимое изменится по мере продвижения. И место, где контент не изменится, может упустить это. Таким образом, u будет получать новый ответ каждый раз

Ответ 16

Интернет-исследователи Ajax Caching: что вы собираетесь делать с этим? предлагает три подхода:

  • Добавьте к строке запроса маркер перебора кеша, например: date = [timestamp]. В jQuery и YUI вы можете сказать им сделать это автоматически.
  • Используйте POST вместо GET
  • Отправлять заголовок ответа HTTP, который специально запрещает браузеру кэшировать его.

Ответ 17

Теперь легко сделать это, включив/отключив параметр кеша в своем аякс-запросе, точно так же, как этот

$(function () {
    var url = 'your url goes here';
    $('#ajaxButton').click(function (e) {
        $.ajax({
            url: url,
            data: {
                test: 'value'
            },
                cache: true, //cache enabled, false to reverse
                complete: doSomething
            });
        });
    });
    //ToDo after ajax call finishes
    function doSomething(data) {
        console.log(data);
    }
});

Ответ 18

Если вы используете IE 9, вам нужно использовать следующее перед определением класса контроллера:

[OutputCache (NoStore = true, Duration = 0, VaryByParam = "*" )]

открытый класс TestController: контроллер

Это предотвратит кеширование браузера.

Подробная информация об этой ссылке: http://dougwilsonsa.wordpress.com/2011/04/29/disabling-ie9-ajax-response-caching-asp-net-mvc-3-jquery/

На самом деле это решило мою проблему.

Ответ 19

Как сказал @Athasach, согласно документам jQuery, $.ajaxSetup({cache:false}) не будет работать, кроме запросов GET и HEAD.

В любом случае вам лучше не отправлять заголовок Cache-Control: no-cache со своего сервера. Это обеспечивает более четкое разделение проблем.

Конечно, это не сработает для служебных URL-адресов, которые вы не принадлежите вашему проекту. В этом случае вы можете подумать о проксинге службы сторонних поставщиков из кода сервера, а не называть его кодом клиента.

Ответ 20

Если вы используете .net ASP MVC, отключите кеширование действия контроллера, добавив в функцию конечной точки следующий атрибут: [OutputCacheAttribute (VaryByParam = "*", Duration = 0, NoStore = true)]

Ответ 21

добавить Math.random() в URL запроса