Запретить кеширование браузером результата вызова AJAX

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

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

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

Рассматривали ли вы выбор другого ответа в качестве принятого?

M4N 22.07.2015 16:31

Вы можете использовать короткое обозначение $.now() вместо того, чтобы каждый раз выполнять (new Date (). GetTime ()).

Dayson 01.07.2011 01:31
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
275
2
313 486
21
Перейти к ответу Данный вопрос помечен как решенный

Ответы 21

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

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

Неправильно. В IE заголовки без кеширования игнорируются для вызовов XMLHttpRequest, как обсуждается здесь: stackoverflow.com/questions/244918/… DateTime (или мой метод .ajaxSetup) - единственные решения, которые действительно работают.

Peter J 30.01.2010 01:35

я только что вставил свою обычную мантру без кеширования, не указано, что это специфично для IE

miceuz 01.02.2010 14:46

Это должно отключить кеширование для всех браузеров: response.setHeader ("Cache-Control", "max-age = 0, no-cache, no-store, post-check = 0, pre-check = 0");

Chris Broski 15.04.2015 20:22

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

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

Объедините Date (). GetTime () вместе с Math.random (), и вы должны быть в безопасности. Кстати, Ext.Ajax также использует getTime (), если указано disableCaching.

vividos 15.12.2008 12:53

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

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

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

Salamander2007 15.12.2008 12:33

А, ладно. Никогда не пробовал, просто вспомнил, что видел кое-что об этом в документации :)

finpingvin 15.12.2008 12:59

Даже не обязательно использовать $ .ajax. Просто используйте .ajaxSetup.

Peter J 09.04.2009 21:12
Ответ принят как подходящий

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

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

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

Я буду отрицать только потому, что это будет проще, если jQuery сделает это, как в ответе Питера Дж. Ваше решение будет работать, но его труднее поддерживать в долгосрочной перспективе.

Niklas Wulff 13.01.2011 15:46

Какая часть этого требует обслуживания? По сравнению с тем, что делает jQuery?

Sunny R Gupta 30.05.2013 13:02

Возможно, стоит отметить, что код new Date().getTime() используется вот так ... var nocache = new Date().getTime(); var path = 'http://hostname.domain.tld/api/somejsonapi/?cache=' + nocache;. Мне потребовалось несколько минут, чтобы самому понять это. Конечно, ?cache может быть любой формулировкой, которая на самом деле не нужна API.

doubleJ 10.07.2013 08:15

+1 даже у Ответ Питера Дж. есть лучший подход, этот ответ не является неправильным и плохим. Я считаю, что DV сделаны, потому что ваш выше Питера (как принято). и OP не появляется на SO с начала 2013 года

Michel Ayres 05.09.2014 17:01
url = url + (-1 === url.indexOf('?') ? '?' : '&') + "__ = " + Number(new Date());
user257319 23.02.2015 14:58

Это единственный способ сработал для меня .. в FF .. Отличная техника. спасибо

Girish Thimmegowda 04.10.2015 13:31

@ salamander2007 Это не должен быть общепринятым ответом, cache: false - правильный подход в JQuery.

user692942 20.07.2020 11:30

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

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

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

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

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

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

Salamander2007 16.12.2008 03:46

Пожалуйста, добавьте пояснение к своему ответу, чтобы другие могли извлечь из него уроки - Зачем, нужен ли запрос POST?

Nico Haase 30.04.2020 18:44

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

$.get("myurl", myCallback)

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

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

+1 Это правильный ответ. Решение Питера J по глобальному отключению кеширования - это плохая практика IMO.

Salman von Abbas 19.04.2012 17:48

Важно отметить, что это только "глобальный" для страницы / запроса.

Peter J 09.05.2012 19:39

+1: кеширование должно зависеть от типа запроса. Некоторым запросам сервера может потребоваться кеширование (где данные сервера статичны), поэтому выбор кеширования на основе запрос по запросу лучше, чем просто выключить все это.

Gone Coding 04.09.2013 20:07

+1 за правильный ответ - предотвращение кеширования для каждого вызова с использованием метода jQuery, а не ручного взлома.

Brendan Hill 17.01.2014 03:02

Еще один хороший ответ. Я должен сказать, что для меня в большинстве случаев глобальное отключение кеша было большим преимуществом. Однако все зависит от того, как разработано ваше приложение. Нет серебряной пули, но в этой ситуации я бы порекомендовал функцию, которая принимает логическое значение для кеширования, функцию для обратного вызова и URL-адрес для модульности. Ручной "взлом" - это нормально, но если вы используете jQuery, по возможности придерживайтесь их функций. Это не только упростит разработку сейчас, но и сделает будущие обновления библиотеки.

Anthony Mason 23.05.2016 16:50

«$ .Get () JQuery будет кэшировать результаты» не совсем верно; использовать кешированный результат может браузер, а не jQuery. При использовании $.ajax с cache: false jQuery добавляет метку времени к URL-адресу, что обеспечивает свежий ответ от сервера.

DigitalDan 02.01.2018 19:59

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

Bob Ray 24.09.2018 18:49

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

$.ajaxSetup({ cache: false });

После расследования (Fiddler) похоже, что jQuery реализует это внутренне, просто добавляя временную метку в любом случае (как обсуждается в другом месте в этих ответах). Для меня метод .ajaxSetup чище (на мой взгляд).

Peter J 30.01.2010 01:33

Почему это должно быть внутри вызова готовности документа? Как я могу быть уверен, что ни один из моих других обработчиков готовых документов (с вызовами ajax) не сработает раньше этого?

Michiel Cornille 28.06.2011 19:29

На самом деле это не обязательно должно быть внутри вызова готовности документа.

Peter J 16.07.2011 01:14

где нам нужно разместить этот кусок кода? И нужно ли нам размещать это на каждой странице, которая вызывает $ .ajax?

Niar 16.02.2013 12:15

Поместите код так, чтобы он вызывался один раз при загрузке страницы, перед любым вызовом $ .ajax.

Peter J 16.02.2013 23:40

Зачем отключать кеширование ajax глобально? Я думаю, что это должно быть сделано для каждого звонка, как то, что делает ответ Джонатана.

Sunny R Gupta 30.05.2013 13:03

Ты прав. Если вы хотите контролировать кеширование для каждого запроса отдельно, а не глобально для всех запросов на странице, дерзайте!

Peter J 30.05.2013 22:48

Этот ответ отлично подходит для меня. Но у меня есть одно сомнение, у меня много функций javascript на одной странице jsp, каждая функция будет внутренне вызывать вызов ajax. Так нужно ли мне писать код в вашем ответе во всех функциях?

Kishan_KP 14.07.2013 13:58

Нет, один раз при загрузке страницы.

Peter J 15.07.2013 00:55

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

Peter J 05.09.2013 23:46

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

Phil 08.02.2014 01:32

Объект JQuery AJAX будет следовать перенаправлениям, поэтому даже если вы отключите кеширование глобально, параметр "_ = {timestamp}", который jQuery добавляет для блокировки кеша браузера, может не перенаправляться с перенаправлением. В этом случае ваш запрос все еще может быть кеширован браузером. Решение состоит в том, чтобы либо убедиться, что вместе с перенаправлениями передается специальный параметр, либо вы отключите кеширование в коде на стороне сервера для этих запросов. (Например, gist.github.com/chrisbloom7/…)

Chris Bloom 09.09.2014 18:57
связь Описание: установка значений по умолчанию для будущих запросов Ajax. Его использование не рекомендуется.
itwebdeveloper 11.08.2015 19:11

Если вы беспокоитесь о влиянии кеширования статического содержимого, jQuery не предотвратит этого, если вы явно не загружаете скрипты и стили через $ .get или тому подобное. Если вы работаете с частичными представлениями, получением ajax и т.п., я настоятельно рекомендую вам реализовать это решение, иначе все может стать волосатым. Я считаю, что проще всего сбросить это на страницу макета / эталона, чтобы не было избыточности.

Anthony Mason 23.05.2016 16:46

Наверное, браузер UC не поддерживает эту опцию.

The_ehT 11.08.2016 16:51

Настоящий вопрос в том, зачем вам это нужно, чтобы это не кешировалось. Если он не должен кэшироваться, потому что он все время изменяется, сервер должен указать, чтобы ресурс не кэшировался. Если он просто иногда меняется (потому что один из ресурсов, от которого он зависит, может измениться), и если у клиентского кода есть способ узнать об этом, он может добавить фиктивный параметр к URL-адресу, который вычисляется из некоторого хэша или даты последнего изменения. этих ресурсов (это то, что мы делаем в ресурсах сценария Microsoft Ajax, чтобы их можно было кэшировать навсегда, но новые версии все еще могут обслуживаться по мере их появления). Если клиент не может знать об изменениях, сервер должен правильно обрабатывать запросы HEAD и сообщать клиенту, использовать ли кешированную версию или нет. Мне кажется, что добавление случайного параметра или указание клиента никогда не кешировать неправильно, потому что кешируемость - это свойство серверного ресурса, и поэтому его следует решать на стороне сервера. Еще один вопрос, который следует задать себе: действительно ли этот ресурс должен обслуживаться через GET или он должен проходить через POST? Это вопрос семантики, но он также имеет последствия для безопасности (есть атаки, которые работают только в том случае, если сервер разрешает GET). POST не будет кэшироваться.

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

7wp 31.03.2011 08:36

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

Jonathan Tran 17.08.2016 01:05

Это мне помогло, ResponseCaching по умолчанию был установлен на 60-метровую сторону сервера. Изменил его на No-Cache, и он перестал кэшировать на клиенте.

mattygee 17.03.2020 19:09

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

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

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

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

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

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

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

Setting cache to false will only work correctly with HEAD and GET requests. It works by appending "_ = {timestamp}" to the GET parameters. The parameter is not needed for other types of requests, except in IE8 when a POST is made to a URL that has already been requested by a GET.

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

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

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

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

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

Это даст нестабильные результаты.

aj.toulan 09.04.2014 18:46

Math.random будет действовать только как параметр, например url? _ = [Math.Random ()], он не имеет ничего общего с нестабильным результатом.

xiaoyifang 10.04.2014 14:01

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

aj.toulan 10.04.2014 22:07

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

Кэширование Ajax в Internet Explorer: что вы собираетесь с этим делать? предлагает три подхода:

  1. Add a cache busting token to the query string, like ?date=[timestamp]. In jQuery and YUI you can tell them to do this automatically.
  2. Use POST instead of a GET
  3. Send a HTTP response header that specifically forbids browsers to cache it

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

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

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

Если вы используете .net ASP MVC, отключите кеширование действия контроллера, добавив следующий атрибут в функцию конечной точки:

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

Вы можете объяснить это дальше? Как этот массив связан с AJAX?

Nico Haase 30.04.2020 18:43

Это не массив, это атрибут в действии контроллера MVC.

Marius 02.05.2020 11:39

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

$(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.info(data);
    }
});

Через 6 лет вы даете такой же ответ, что и Джонатан? ಠ_ಠ

redent84 26.02.2016 17:21

люди могут сказать, что это через 6 лет после публикации вопроса. И мой ответ на этот вопрос отличается от любого другого, не говоря уже о том, что в настоящее время он правильный. Отвечать на такие вопросы не для «спрашивающего», а для сообщества и новичков! В любом случае спасибо за добавление разъяснений!

El Don 27.02.2016 02:20

А какая разница между твоим и этим stackoverflow.com/a/735084/469218?

redent84 28.02.2016 20:37

может это ясность, с точки зрения новичка, задающего такой вопрос !!

El Don 28.02.2016 22:49

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

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

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

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

Может быть, глупый вопрос, но если мои изображения ajax вернут, будут ли изображения кешироваться? Чтобы избежать массовых запросов Amazon S3?

Marcelo Agimóvel 04.07.2018 16:31

Марсело Агимовел, я считаю, что это может быть отдельный ТАК вопрос.

Aidin 01.06.2019 01:12

добавить заголовок

headers: {
                'Cache-Control':'no-cache'
            }

Пожалуйста, добавьте пояснения к своему ответу, чтобы другие могли извлечь из него уроки - где следует ли добавлять такие заголовки?

Nico Haase 30.04.2020 18:43

Другие вопросы по теме