Заставить браузер очистить кеш

284

Есть ли способ, которым я могу разместить некоторый код на своей странице, чтобы при посещении сайта он очищал кеш браузера, чтобы они могли просматривать изменения?

Используемые языки: ASP.NET, VB.NET и, конечно, HTML, CSS и jQuery.

Адам
источник
Хорошее решение или обходной путь для «очистки кэша» можно найти здесь: stackoverflow.com/a/43676353/2008111
caramba

Ответы:

351

Если это примерно так .cssи .jsизменится, один из способов - «очистить кеш», добавив что-то вроде « _versionNo» к имени файла для каждого выпуска. Например:

script_1.0.css // This is the URL for release 1.0
script_1.1.css // This is the URL for release 1.1
script_1.2.css // etc.

Или альтернативно сделайте это после имени файла:

script.css?v=1.0 // This is the URL for release 1.0
script.css?v=1.1 // This is the URL for release 1.1
script.css?v=1.2 // etc.

Вы можете проверить эту ссылку, чтобы увидеть, как она может работать.

Фермин
источник
10
Это довольно хорошее решение, и даже может быть автоматизировано вашей системой сборки (и должно быть). Stackoverflow, например, использует этот подход.
Дероберт
7
ТАК использует GET аргументы сейчас.
Саиб Амини
60
А еще лучше, чтобы сохранить имя файла как есть, но добавить номер версии в качестве параметра строки запроса, то есть script.js?v=1.2. (Или, если вы не отслеживаете версии, просто используйте время последнего изменения файла, что еще проще). Не уверен, что это имел в виду предыдущий комментатор!
Doin
5
Как все это делают с контролем версий? Похоже на настоящую боль.
Шон
1
@Shawn Управление версиями, вы можете <link />динамически отображать теги и вставлять версию приложения в качестве параметра строки запроса. В качестве альтернативы, некоторые CMS будут иметь «версию клиентских ресурсов» в виде параметра для всей CMS, который добавляется - администратор сайта может вручную увеличить этот номер версии, а обновления CMS также могут автоматически обновлять его. Итог: необходимо динамически отображать URL-адреса файлов.
Йерун
103

Посмотрите в кэш-контроль и мета-тег истекает .

<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="EXPIRES" CONTENT="Mon, 22 Jul 2002 11:12:01 GMT">

Другой распространенной практикой является добавление постоянно меняющихся строк в конец запрошенных файлов. Например:

<script type="text/javascript" src="main.js?v=12392823"></script>

Сэмпсон
источник
44
Это мало поможет в том случае, если он уже кеширован - поскольку он кешируется, сервер не будет запрашиваться и, следовательно, не может отвечать без кэширования. Кроме того, этот метатег на самом деле не должен использоваться, как говорится в примечании, он будет порваться с веб-кешами.
Дероберт
1
+1 то, что сказала Дероберт. Всегда лучше использовать заголовки HTTP, чтобы предлагать политику кэширования клиентам и веб-кешам, но даже это не работает для принудительной перезагрузки кэша.
4
+1 за ваше второе решение. У меня есть проблема, что кэш должен быть очищен только в первый раз после того, как какой-то администратор сделал обновление. Этот подход должен решить это
Жюль Колле
Полное отключение кеша обычно плохая идея.
Иордания,
73

Обновление 2012

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

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

Это пример кода из Руководства для начинающих по использованию кэша приложений на HTML5 Rocks, объясняющий, как обновить пользователей до последней версии вашего сайта:

// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {

  window.applicationCache.addEventListener('updateready', function(e) {
    if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
      // Browser downloaded a new app cache.
      // Swap it in and reload the page to get the new hotness.
      window.applicationCache.swapCache();
      if (confirm('A new version of this site is available. Load it?')) {
        window.location.reload();
      }
    } else {
      // Manifest didn't changed. Nothing new to server.
    }
  }, false);

}, false);

См. Также Использование кеша приложений в Mozilla Developer Network для получения дополнительной информации.

Обновление 2016

Вещи быстро меняются в Интернете. Этот вопрос был задан в 2009 году, а в 2012 году я опубликовал обновление о новом способе решения проблемы, описанной в вопросе. Прошло еще 4 года, и теперь кажется, что это уже устарело. Спасибо cgaldiolo за то, что указал на это в комментариях.

В настоящее время по состоянию на июль 2016 года стандарт HTML, раздел 7.9 «Автономные веб-приложения» содержит предупреждение об устаревании:

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

То же самое касается использования кэша приложений в Mozilla Developer Network, на который я ссылался в 2012 году:

Устаревшая
Эта функция была удалена из веб-стандартов. Хотя некоторые браузеры все еще могут поддерживать его, он находится в процессе удаления. Не используйте его в старых или новых проектах. Страницы или веб-приложения, использующие его, могут сломаться в любое время.

См. Также Ошибка 1204581 - Добавьте уведомление об устаревании для AppCache, если включен перехват выборки работника службы .

RSP
источник
1
Означает ли это, что вам нужно использовать и поддерживать файл манифеста кэша?
Сэм
Предупреждение: интерфейс кэша приложений (AppCache) устарел
cgaldiolo
59
Итак, какова текущая рекомендация на 2017 год?
Гаррет
Основная проблема, которую я видел в этой теме, - это когда устройство, которое использует зритель, продолжает использовать кэшированные версии, потому что внутренняя память устройства пользователя заполняется. кажется, что он застрял в кэшированной версии страницы и не будет обновлять какие-либо элементы в документе. это происходит только в Chrome? это единственный браузер, в котором я когда-либо сталкивался.
user2585548
4
2017: Использование сервисных работников.
digitai
27

Не как таковой. Один из способов заключается в отправке соответствующих заголовков при доставке контента, чтобы заставить браузер перезагрузиться:

Убедитесь, что веб-страница не кэшируется во всех браузерах.

Если вы "cache header"ищете или что-то подобное здесь, на SO, вы найдете конкретные примеры ASP.NET.

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

myimage.gif?random=1923849839
Пекка
источник
2
Это действительно лучше, чтобы правильно версии файлов. Это довольно большая трата пропускной способности, и, что, возможно, более важно, сильно замедляет работу вашего сайта.
Дероберт
8
Это действительно зависит от ситуации, не так ли? Если вы программируете CMS и вам необходимо убедиться, что все измененные ресурсы обновлены должным образом, иногда невозможно обойти один из этих двух вариантов.
Пекка
Решения, подобные этому, следует признать отрицательным. Это зависит от нас, чтобы сохранить как можно меньше выбросов CO2 в Интернете.
время
14

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

/Content/css/Site.css?version={FileVersionNumber}

Вот пример ASP.NET MVC.

<link href="@Url.Content("~/Content/Css/Reset.css")?version=@this.GetType().Assembly.GetName().Version" rel="stylesheet" type="text/css" />

Не забудьте обновить версию сборки.

Паулюс Залиадуонис
источник
Спасибо за этот ответ, но как это сделать, когда мы добавляем ресурсы в BundleTable, пожалуйста?
Торегуа
В моем случае это возвращало «0.0.0.0» в качестве версии. Чтобы получить версию dll вашего MVC-приложения, используйте вместо этого:?version=@ViewContext.Controller.GetType().Assembly.GetName().Version
CGodo
1
Я обнаружил, что это не позволяет Firefox и Chrome полностью кэшировать содержимое.
Сэм
10

У меня была похожая проблема, и вот как я ее решил:

  1. В index.htmlфайле я добавил манифест:

    <html manifest="cache.manifest">
  2. В <head>раздел включен скрипт обновления кеша:

    <script type="text/javascript" src="update_cache.js"></script>
  3. В <body>разделе я вставил функцию загрузки:

    <body onload="checkForUpdate()">
  4. В cache.manifestя положил все файлы, которые я хочу кешировать. Теперь важно, чтобы он работал в моем случае (Apache), просто обновляя каждый раз комментарий «версия». Это также опция для имен файлов с "? Ver = 001" или что-то в конце имени, но это не нужно . Изменение только # version 1.01запускает событие обновления кэша.

    CACHE MANIFEST
    # version 1.01
    style.css
    imgs/logo.png
    #all other files
    

    Важно включать пункты 1., 2. и 3. только в index.html. В противном случае

    GET http://foo.bar/resource.ext net::ERR_FAILED

    происходит потому, что каждый «дочерний» файл пытается кэшировать страницу, пока страница уже кэширована.

  5. В update_cache.jsфайл я положил этот код:

    function checkForUpdate()
    {
        if (window.applicationCache != undefined && window.applicationCache != null)
        {
            window.applicationCache.addEventListener('updateready', updateApplication);
        }
    }
    function updateApplication(event)
    {
        if (window.applicationCache.status != 4) return;
        window.applicationCache.removeEventListener('updateready', updateApplication);
        window.applicationCache.swapCache();
        window.location.reload();
    }
    

Теперь вы просто меняете файлы и в манифесте вам необходимо обновить комментарий к версии. Теперь посещение страницы index.html позволит обновить кеш.

Части решения не мои, но я нашел их через интернет и собрал так, чтобы это работало.

Войтек Мазурек
источник
Могу ли я узнать, где написано CACHE.MANIFEST.
Швета Гулати
1
Shweta Gulati Файл манифеста должен находиться в той же папке, что и файл «index». Сколько времени это не работает?
Войтек Мазурек
1
@ShwetaGulati Да, кеш не обнаруживает изменения в html-файлах, поэтому необходимо обновить номер версии в файле манифеста, потому что именно он проверяется на наличие изменений. Тебе действительно трудно помочь, потому что я не знаю деталей. Скажите, пожалуйста, поместили ли вы все желаемые кэшируемые файлы в манифест? Путь должен быть относительно файла манифеста. Вы можете дать мне адрес своего сайта, и я могу сказать, в чем дело :)
Войтек Мазурек
1
@ShwetaGulati Это потому, что браузер автоматически кэширует некоторые файлы, чтобы ускорить загрузку страницы. Это поведение по умолчанию и зависит только от браузера, так что вы не можете установить его каким-либо образом. В частности, файлы js находятся в области видимости браузера, поскольку они обычно используются на всех страницах веб-сайта, поэтому целесообразно их кешировать. Нет другого способа, кроме как записать все имена файлов в файл манифеста для кэширования всех файлов. Если найдешь что-нибудь, скажи мне, потому что мне это тоже нужно :)
Wojtek Mazurek
1
Абсолютный путь к вашим файлам не имеет значения. Относительный путь от адреса имеет значение, потому что браузер отправляет запрос на файлы. F.ex: У меня есть домен example.com, и он находится на serwer names.com. Мое место на нем - example.names.com. Поэтому я присоединяю свой домен example.com к своему серверному пространству example.names.com в качестве перенаправления. Для этого мне нужно установить папку как цель этого перенаправления. Поэтому, если я хочу иметь несколько сайтов на example.names.com, я создаю папку «name1», устанавливаю редирект на нее и помещаю все свои файлы внутрь. Пути отсчитываются отсюда. Если у меня есть файл name1 \ scripts \ test.js в файле манифеста, я пишу scripts \ test.js.
Войтек Мазурек
7

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

<img src="/photos/userid_73.jpg?random=<?php echo rand() ?>" ...

РЕДАКТИРОВАТЬ Как указывали другие, следующее является гораздо более эффективным решением, поскольку оно будет перезагружать изображения только после их изменения, определяя это изменение по размеру файла:

<img src="/photos/userid_73.jpg?modified=<? filemtime("/photos/userid_73.jpg")?>"
Zeeshan
источник
29
Это совсем не элегантно, это заставит сайт перезагружать изображение каждый раз, тратя много времени на загрузку ресурсов, лучшее решение будет использовать размер файла вместо случайного числа, это сделает кэш-память только для повторной проверки, когда файл фактически изменения
Роберто Аросемена
8
Или хеш изображения байтов
Тейлор Эдмистон
1
Все зависит от требований пользователя. Для большого количества фотографий сценарий будет отличаться от нескольких фотографий. Проверка размера файла сохранит пропускную способность, но также добавит дополнительную обработку, потенциально замедляя загрузку страницы. В моем случае, когда картинки менялись довольно часто, и для делового решения было важно, чтобы пользователь получал самые современные, это было идеальное решение.
Зеешан
Вы можете сделать это статическим значением даже в конфигурации, это ни в коем случае не идеальный подход.
Провидец
3
<img src = "/ photos / userid_73.jpg ?ified = <? = filemtime (" / photos / userid_73.jpg ")?>" было бы гораздо полезнее!
Fusca Software
4

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

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

Джон
источник
2

Обновление URL до следующего работает для меня:

/custom.js?id=1

Добавляя уникальный номер после ?id=и увеличивая его для новых изменений, пользователям не нужно нажимать, CTRL + F5чтобы обновить кэш. Кроме того, вы можете добавить хеш или строковую версию текущего времени или эпохи после?id=

Что-то вроде ?id=1520606295

nPcomp
источник
1

Вот страница MDSN по настройке кэширования в ASP.NET.

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
Response.Cache.SetCacheability(HttpCacheability.Public)
Response.Cache.SetValidUntilExpires(False)
Response.Cache.VaryByParams("Category") = True

If Response.Cache.VaryByParams("Category") Then
   '...
End If
Дейв Сверски
источник
1

Не уверен, что это действительно может вам помочь, но именно так кэширование должно работать в любом браузере. Когда браузер запрашивает файл, он всегда должен отправлять запрос на сервер, если не существует «автономного» режима. Сервер будет читать некоторые параметры, такие как дата изменения или etags.

Сервер вернет сообщение об ошибке 304 для NOT MODIFIED, и браузер должен будет использовать его кэш. Если etag не проверяется на стороне сервера или дата изменения ниже текущей даты изменения, сервер должен возвратить новый контент с новой датой изменения или etags или обоими.

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

Вот как это должно быть сделано. Использование случайных параметров или номера версии в URL больше похоже на взлом.

http://www.checkupdown.com/status/E304.html http://en.wikipedia.org/wiki/HTTP_ETag http://www.xpertdeveloper.com/2011/03/last-modified-header-vs- истекают-заголовок-VS-ETAG /

После прочтения я увидел, что есть также срок годности. Если у вас есть проблемы, возможно, у вас установлена ​​дата истечения срока действия. Другими словами, когда браузер будет кэшировать ваш файл, так как у него есть дата истечения срока действия, он не должен запрашивать его снова до этой даты. Другими словами, он никогда не будет запрашивать файл на сервере и никогда не получит 304 без изменений. Он будет просто использовать кеш, пока не истечет дата истечения срока или пока кеш не будет очищен.

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

Если люди часто обновляются, а файл не сильно меняется, то может быть целесообразно установить большую дату истечения срока действия.

Мои 2 цента!

Лоик Фор-Лакруа
источник
1

Я реализовал это простое решение, которое работает для меня (еще не в производственной среде):

function verificarNovaVersio() {
    var sVersio = localStorage['gcf_versio'+ location.pathname] || 'v00.0.0000';
    $.ajax({
        url: "./versio.txt"
        , dataType: 'text'
        , cache: false
        , contentType: false
        , processData: false
        , type: 'post'
     }).done(function(sVersioFitxer) {
        console.log('Versió App: '+ sVersioFitxer +', Versió Caché: '+ sVersio);
        if (sVersio < (sVersioFitxer || 'v00.0.0000')) {
            localStorage['gcf_versio'+ location.pathname] = sVersioFitxer;
            location.reload(true);
        }
    });
}

У меня есть маленький файл, где находится HTML:

"Versio.txt":

v00.5.0014

Эта функция вызывается на всех моих страницах, поэтому при загрузке она проверяет, является ли значение версии localStorage ниже текущей версии и выполняет ли

location.reload(true);

... для принудительной перезагрузки с сервера, а не из кеша.

(очевидно, вместо localStorage вы можете использовать куки или другое постоянное клиентское хранилище)

Я выбрал это решение для его простоты, потому что только ведение одного файла "versio.txt" заставит весь сайт перезагрузиться.

Метод queryString сложно реализовать, и он также кэшируется (если вы переключитесь с v1.1 на предыдущую версию, загрузка из кэша будет выполняться, то это означает, что кэш не очищается, сохраняя все предыдущие версии в кэше).

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

Надеюсь, поможет.

Seak
источник
0

Существует один прием, который можно использовать. Он заключается в добавлении параметра / строки к имени файла в теге сценария и изменении его при внесении изменений в файл.

<script src="myfile.js?version=1.0.0"></script>

Браузер интерпретирует всю строку как путь к файлу, хотя после «?» параметры. Таким образом, теперь происходит то, что в следующий раз, когда вы обновите свой файл, просто измените номер в теге script на вашем веб-сайте (пример <script src="myfile.js?version=1.0.1"></script>), и каждый пользовательский браузер увидит, что файл изменился, и получит новую копию.

Joish
источник
0

Заставить браузеры очистить кеш или перезагрузить правильные данные? Я попробовал большинство решений, описанных в stackoverflow, некоторые из них работают, но через некоторое время он в конце концов кеширует и отображает предыдущий загруженный скрипт или файл. Есть ли другой способ очистить кэш (css, js и т. Д.) И фактически работать во всех браузерах?

До сих пор я обнаружил, что определенные ресурсы могут быть перезагружены индивидуально, если вы измените дату и время для ваших файлов на сервере. «Очистить кеш» не так просто, как должно быть. Вместо очистки кэша в моих браузерах я понял, что «касание» кэшированных файлов сервера фактически изменит дату и время исходного файла, кэшированного на сервере (протестировано на Edge, Chrome и Firefox), и большинство браузеров автоматически загрузят большинство текущая свежая копия того, что находится на вашем сервере (код, графика и любые мультимедиа тоже). Я предлагаю вам просто скопировать самые последние сценарии на сервере и решить проблему "сделать что-то на ощупь" перед запуском вашей программы, поэтому она изменит дату всех ваших проблемных файлов на самую последнюю дату и время, а затем загрузит свежую копию в ваш браузер:

<?php
   touch('/www/sample/file1.css');
   touch('/www/sample/file2.js');
?>

тогда ... остальная часть вашей программы ...

Мне потребовалось некоторое время, чтобы решить эту проблему (поскольку многие браузеры по-разному работают с разными командами, но все они проверяют время файлов и сравнивают их с загруженной в браузере копией, если обновление даты и времени выполнят обновление), если вы не может идти по правильному пути, всегда есть другое полезное и лучшее решение. С наилучшими пожеланиями и счастливого кемпинга. Кстати коснитесь (); или альтернативы работают на многих языках программирования, включая javascript bash sh php, и вы можете включить или вызвать их в html.

Луис Х Кабрехо
источник
1
если файл изменен, временная метка уже все равно изменена, поэтому принудительное ее повторное использование не имеет смысла.
Fusca Software
Сенсорная команда не меняет файл вообще. Он изменяет атрибут даты и времени, преобразовывая его в более новую версию, обманывая браузер, чтобы загрузить его как новую копию.
Луис Х Кабрехо
-1

Вы хотите очистить кеш или просто убедитесь, что ваша текущая (измененная?) Страница не кешируется?

Если последнее, это должно быть так же просто, как

<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
Тим Кроне
источник
Недавно я прочитал об этом подходе в публикации Chrome, и нашел только последовательные результаты на нескольких живых серверах, локальных хостах и ​​файловых ресурсах Windows ... с Firefox 3.6.
Данджа