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


283

Чи є спосіб я помістити якийсь код на свою сторінку, щоб коли хтось відвідував сайт, він очищає кеш браузера, щоб вони могли переглянути зміни?

Використовувані мови: ASP.NET, VB.NET, і звичайно HTML, CSS та jQuery.


Приємне рішення або вирішення питання "очистити кеш" можна знайти тут: stackoverflow.com/a/43676353/2008111
caramba

Відповіді:


350

Якщо це стосується .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 настройку, яка додається - адміністратор сайту може вручну збільшити цю версію nr, а оновлення CMS також можуть автоматично оновити її. Підсумок: URL-адреси файлів потрібно відображати динамічно.
Єроен

103

Загляньте в кеш-контроль і тег META закінчується .

<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, в якому пояснюється, як оновити користувачів до новітньої версії вашого сайту:

// 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.

Оновлення 2016 року

У Інтернеті все швидко змінюється. Це запитання було задано в 2009 році, а в 2012 році я опублікував оновлення про новий спосіб вирішення проблеми, описаної в запитанні. Минуло ще 4 роки, і зараз здається, що це вже застаріло. Завдяки cgaldiolo за те, що він це вказав у коментарях.

Наразі, станом на липень 2016 року, Стандарт Стандарт HTML, Розділ 7.9, Офлайн-Веб-додатки містить попередження про припинення роботи:

Ця функція знаходиться в процесі видалення з веб-платформи. (Це довгий процес, який займає багато років.) Використання будь-якої функції офлайн-веб-додатків на даний момент вкрай не рекомендується. Замість цього використовуйте сервісних працівників.

Як і використання кешу додатків у мережі розробників Mozilla, на який я посилався у 2012 році:

Застаріла
Ця функція була видалена з веб-стандартів. Хоча деякі веб-переглядачі можуть все-таки підтримувати його, він перебуває в процесі випадання. Не використовуйте його у старих чи нових проектах. Сторінки або веб-додатки, що використовують його, можуть зламатися в будь-який час.

Див. Також Помилка 1204581 - Додайте повідомлення про анулювання для AppCache, якщо ввімкнено перехоплення службовим працівником .


1
Це означає, що вам потрібно використовувати та підтримувати файл маніфесту кешу?
Сем

Попередження: Інтерфейс кеш-програми (AppCache) застарілий
cgaldiolo

59
Отже, яка нинішня рекомендація станом на 2017 рік?
Гаррет

Основна проблема, яку я бачив у цій темі, - це коли пристрій, яким користувач переглядає, продовжує користуватися кешованими версіями, оскільки внутрішня пам'ять пристрою користувачів набирається. схоже, що він застряг у кешованій версії сторінки і не оновлює будь-які елементи документа. це трапляється лише в хромі ?? це єдиний браузер, який я відчував.
користувач2585548

4
2017 рік: використовуйте службовців.
digitai

27

Не як такий. Один із способів - надсилати відповідні заголовки під час доставки вмісту, щоб змусити браузер перезавантажити:

Переконайтеся, що веб-сторінка не кешована у всіх браузерах.

Якщо ви шукаєте "cache header"щось подібне тут на SO, ви знайдете конкретні приклади ASP.NET.

Інший, менш чистий, але іноді єдиний спосіб, якщо ви не можете керувати заголовками на стороні сервера, - додавання випадкового параметра GET до ресурсу, який викликається:

myimage.gif?random=1923849839

2
Дійсно краще правильно версії файлів. Це досить велика витрата пропускної здатності, і, що, що ще важливіше, значно сповільнює ваш сайт.
derobert

8
Це насправді залежить від ситуації, чи не так? Якщо ви програмуєте CMS і вам потрібно переконатися, що всі змінені ресурси належним чином оновлюються, іноді не обійтися одним із цих двох варіантів.
Pekka

Такі рішення слід визнати негативними. Ми вирішуємо максимально знизити рівень Інтернет в Інтернеті.
терміни

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
Shweta Gulati

1
Shweta Gulati Файл маніфесту повинен бути в тій же папці, що і файл "індексу". У який час це не працює?
Войтек Мазурек

1
@ShwetaGulati Так, кеш не виявляє змін у html-файлах - саме тому вам потрібно оновити номер версії у файлі маніфесту, оскільки саме він перевіряється на зміни. Вам справді важко допомогти, тому що я не знаю деталей. Скажіть, будь ласка, чи ви помістили всі потрібні для кешування файли в маніфест? Шлях повинен бути відносно файлу маніфесту. Ви можете дати мені адресу вашого веб-сайту, і я можу сказати, в чому справа :)
Войтек Мазурек

1
@ShwetaGulati Це тому, що браузер автоматично кешує деякі файли для швидшого завантаження сторінки. Це поведінка за замовчуванням і залежить лише від веб-переглядача, тому ви не можете його встановлювати жодним чином. Особливо js-файли знаходяться в межах браузера, оскільки вони використовуються зазвичай на всіх сторінках веб-сайту, тому розумно кешувати їх. Немає іншого способу, аніж записати всі імена файлів у файл маніфесту для кешування всіх файлів. Якщо ви знайдете будь-яке, скажіть мені, бо мені це теж потрібно :)
Войтек Мазурек

1
Абсолютний шлях до ваших файлів не має значення. Відносний шлях від адресних питань, оскільки браузер надсилає запит на файли. F.ex: У мене є домен example.com і він розміщений на сервері names.com. Мій простір на ньому - example.names.com. Тому я приєдную свій домен example.com до простору сервера example.names.com як переспрямовування. Для цього мені потрібно встановити папку як мету цього переадресації. Отже, якщо я хочу мати кілька сайтів на example.names.com, я створюю папку "name1", встановлюю переспрямування на неї і ввожу всі мої файли всередину. Звідси рахуються шляхи. Якщо у файлі маніфесту я name1 \ scriptpts \ test.js, я пишу сценарії \ test.js.
Войтек Мазурек

7

У мене був випадок, коли я б фотографував клієнтів в Інтернеті, і мені потрібно буде оновити div, якщо фотографію буде змінено. Браузер все ще показував стару фотографію. Тому я скористався викликом випадкової змінної GET, яка була б унікальною щоразу. Ось це, якби це могло комусь допомогти

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

EDIT Як зазначають інші, наступне є набагато ефективнішим рішенням, оскільки воно буде завантажувати зображення лише тоді, коли вони змінені, ідентифікуючи цю зміну за розміром файлу:

<img src="/photos/userid_73.jpg?modified=<? filemtime("/photos/userid_73.jpg")?>"

29
Це зовсім не елегантно, це би змусило сайт перезавантажувати зображення щоразу, витрачаючи багато часу на завантаження ресурсів, кращим рішенням було б використовувати розмір файлів замість випадкового числа, це зробить кеш оновлення лише тоді, коли файл насправді зміни
Роберто Аросемена

8
Або хеш байтів зображення
Тейлор Едмістон

1
Все залежить від потреб користувача. Для великої кількості фотографій сценарій був би іншим, ніж кілька фотографій. Перевірка розміру файлу дозволить заощадити пропускну здатність, але також додасть додаткову обробку, що потенційно уповільнить завантаження сторінки. У моєму випадку, коли зображення змінювались досить часто, і було важливим бізнес-рішенням, щоб користувач отримав найактуальніші, це було ідеальним рішенням.
Зеешан

Ви можете зробити це статичним значенням навіть у конфігурації, це аж ніяк не є ідеальним підходом.
Сір

3
<img src = "/ photos / userid_73.jpg? modified = <? = filemtime (" / photos / userid_73.jpg ")?>" було б набагато кориснішим!
Fusca Software

4

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

Сюди входять вкладене, ітераційне тестування скриптів (велике!) Та зламані сторонні програмні рішення. Жодне з наведених тут рішень не є адекватним для вирішення таких загальних сценаріїв. Більшість веб-браузерів є занадто агресивним кешуванням і не надають розумних засобів, щоб уникнути цих проблем.



2

Оновлення URL-адреси для наступних робіт для мене:

/custom.js?id=1

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

Щось на зразок ?id=1520606295


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

Не впевнений, чи це може вам допомогти, але саме так кешування має працювати в будь-якому браузері. Коли браузер запитує файл, він завжди повинен надсилати запит на сервер, якщо не існує режиму "офлайн". Сервер буде читати деякі параметри, такі як зміна дати або етаги.

Сервер поверне відповідь про помилку 304 для НЕ МОДИФІКОВАНО, і браузер повинен буде використовувати кеш. Якщо етаг не підтверджується на стороні сервера або змінена дата знаходиться нижче поточної модифікованої дати, сервер повинен повернути новий вміст з новою модифікованою датою або етагами або обома.

Якщо дані кешування не надсилаються до браузера, я думаю, що поведінка невизначена, браузер може або не може кешувати файл, який не вказує, як вони кешовані. Якщо у відповіді встановити параметри кешування, вони кешуватимуть ваші файли правильно, і сервер може вирішити повернути помилку 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-етаг /

Прочитавши, я побачив, що також є термін дії. Якщо у вас є проблеми, можливо, у вас встановлена ​​дата закінчення терміну дії. Іншими словами, коли веб-переглядач буде кешувати ваш файл, оскільки у нього термін дії закінчується, йому не слід було б запитувати його ще до цієї дати. Іншими словами, він ніколи не запитає файл на сервер і ніколи не отримає 304, не змінений. Він просто використовувати кеш, поки не буде досягнуто термін придатності або кеш не буде очищено.

Так що я здогадуюсь, у вас є якийсь термін придатності, і ви повинні використовувати останньо змінені етаги або суміш усіх цих даних і переконайтесь, що немає терміну придатності.

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

Мої 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 ви можете використовувати файли cookie або інші постійні клієнтські сховища)

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

Метод queryString важко реалізувати і він також кешований (якщо ви перейдете з v1.1 на попередню версію, завантажуватиметься з кеша, то це означає, що кеш не розмивається, зберігаючи всі попередні версії в кеші).

Я трохи новачок, і я буду вдячний за вашу професійну перевірку та огляд, щоб переконатися, що мій метод є хорошим підходом.

Сподіваюся, це допомагає.



0

Є один трюк, який можна використати. Трюк - додати параметр / рядок до імені файлу в тезі сценарію та змінити його, коли ви змінюєте файл.

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

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


0

Змусити браузерів очистити кеш-пам'ять або перезавантажити правильні дані? Я спробував більшість рішень, описаних у stackoverflow, деякі роботи, але через деякий час він кешує з часом і відображає попередній завантажений сценарій або файл. Чи є інший спосіб, який би очистив кеш (css, js тощо) і фактично працював у всіх браузерах?

Я досі встановив, що конкретні ресурси можна перезавантажувати індивідуально, якщо ви зміните дату та час у своїх файлах на сервері. "Очистити кеш-пам'ять" не так просто, як має бути. Замість очищення кешу в моїх браузерах я зрозумів, що "торкання" кешованих файлів сервера насправді змінить дату та час вихідного файлу, кешованого на сервері (випробувано в Edge, Chrome і Firefox), і більшість браузерів автоматично завантажуватимуть найбільше поточна свіжа копія того, що на вашому сервері (код, графіка і будь-яка мультимедіа). Я пропоную вам просто скопіювати найактуальніші сценарії на сервер та вирішити "зробити сенсорну річ" перед запуском програми, щоб вона змінила дату всіх ваших проблемних файлів на найактуальнішу дату та час, після чого завантажується нова копія до вашого браузера:

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

потім ... решта вашої програми ...

Щоб вирішити цю проблему, у мене знадобився певний час (оскільки багато браузерів діють по-різному на різні команди, але всі вони перевіряють час файлів і порівнюють із завантаженою вами копією у вашому браузері, якщо різні дати та час оновлять оновлення), якщо ви не може йти належним правильним шляхом, завжди є інше корисне і краще рішення. З найкращими побажаннями та щасливим кемпінгом. До речі touch (); або альтернативи працюють у багатьох мовах програмування, включаючи JavaScript bash sh php, і ви можете їх включити або зателефонувати в html.


1
якщо файл змінено, часова мітка все одно вже змінена, тому немає жодної користі змушувати її знову.
Fusca Software

Командна сенсорна команда зовсім не змінює файл. Він змінює атрибут дати та часу, перетворюючи його на новішу версію, що обманює браузер, щоб завантажити його як нову копію.
Луїс Х Кабреджо

-1

Ви хочете очистити кеш або просто переконайтеся, що ваша поточна (змінена?) Сторінка не кешована?

Якщо остання, вона повинна бути такою ж простою

<META HTTP-EQUIV="Pragma" CONTENT="no-cache">

Нещодавно я читав про цей підхід у публікаціях у Chrome, і виявив стійкі результати лише на кількох живих серверах, файлах localhost та Windows ... за допомогою Firefox 3.6.
danjah
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.